1 #include "ldap_config_mgr.hpp" 2 #include "ldap_config.hpp" 3 4 #include "utils.hpp" 5 #include <filesystem> 6 #include <fstream> 7 #include <sstream> 8 9 namespace phosphor 10 { 11 namespace ldap 12 { 13 14 constexpr auto nscdService = "nscd.service"; 15 constexpr auto LDAPscheme = "ldap"; 16 constexpr auto LDAPSscheme = "ldaps"; 17 18 using namespace phosphor::logging; 19 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 20 namespace fs = std::filesystem; 21 using Argument = xyz::openbmc_project::Common::InvalidArgument; 22 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 23 using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed; 24 25 using Line = std::string; 26 using Key = std::string; 27 using Val = std::string; 28 using ConfigInfo = std::map<Key, Val>; 29 30 void ConfigMgr::startOrStopService(const std::string& service, bool start) 31 { 32 if (start) 33 { 34 restartService(service); 35 } 36 else 37 { 38 stopService(service); 39 } 40 } 41 42 void ConfigMgr::restartService(const std::string& service) 43 { 44 try 45 { 46 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 47 SYSTEMD_INTERFACE, "RestartUnit"); 48 method.append(service.c_str(), "replace"); 49 bus.call_noreply(method); 50 } 51 catch (const sdbusplus::exception::SdBusError& ex) 52 { 53 log<level::ERR>("Failed to restart service", 54 entry("SERVICE=%s", service.c_str()), 55 entry("ERR=%s", ex.what())); 56 elog<InternalFailure>(); 57 } 58 } 59 void ConfigMgr::stopService(const std::string& service) 60 { 61 try 62 { 63 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 64 SYSTEMD_INTERFACE, "StopUnit"); 65 method.append(service.c_str(), "replace"); 66 bus.call_noreply(method); 67 } 68 catch (const sdbusplus::exception::SdBusError& ex) 69 { 70 log<level::ERR>("Failed to stop service", 71 entry("SERVICE=%s", service.c_str()), 72 entry("ERR=%s", ex.what())); 73 elog<InternalFailure>(); 74 } 75 } 76 77 std::string ConfigMgr::createConfig( 78 std::string lDAPServerURI, std::string lDAPBindDN, std::string lDAPBaseDN, 79 std::string lDAPBindDNPassword, CreateIface::SearchScope lDAPSearchScope, 80 CreateIface::Create::Type lDAPType, std::string groupNameAttribute, 81 std::string userNameAttribute) 82 { 83 bool secureLDAP = false; 84 85 if (isValidLDAPURI(lDAPServerURI, LDAPSscheme)) 86 { 87 secureLDAP = true; 88 } 89 else if (isValidLDAPURI(lDAPServerURI, LDAPscheme)) 90 { 91 secureLDAP = false; 92 } 93 else 94 { 95 log<level::ERR>("bad LDAP Server URI", 96 entry("LDAPSERVERURI=%s", lDAPServerURI.c_str())); 97 elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"), 98 Argument::ARGUMENT_VALUE(lDAPServerURI.c_str())); 99 } 100 101 if (secureLDAP && !fs::exists(tlsCacertFile.c_str())) 102 { 103 log<level::ERR>("LDAP server's CA certificate not provided", 104 entry("TLSCACERTFILE=%s", tlsCacertFile.c_str())); 105 elog<NoCACertificate>(); 106 } 107 108 if (lDAPBindDN.empty()) 109 { 110 log<level::ERR>("Not a valid LDAP BINDDN", 111 entry("LDAPBINDDN=%s", lDAPBindDN.c_str())); 112 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"), 113 Argument::ARGUMENT_VALUE(lDAPBindDN.c_str())); 114 } 115 116 if (lDAPBaseDN.empty()) 117 { 118 log<level::ERR>("Not a valid LDAP BASEDN", 119 entry("LDAPBASEDN=%s", lDAPBaseDN.c_str())); 120 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"), 121 Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str())); 122 } 123 124 // With current implementation we support only two default LDAP server. 125 // which will be always there but when the support comes for additional 126 // account providers then the create config would be used to create the 127 // additional config. 128 129 std::string objPath; 130 131 if (static_cast<ConfigIface::Type>(lDAPType) == ConfigIface::Type::OpenLdap) 132 { 133 openLDAPConfigPtr.reset(nullptr); 134 objPath = openLDAPDbusObjectPath; 135 openLDAPConfigPtr = std::make_unique<Config>( 136 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(), 137 tlsCertFile.c_str(), secureLDAP, lDAPServerURI, lDAPBindDN, 138 lDAPBaseDN, std::move(lDAPBindDNPassword), 139 static_cast<ConfigIface::SearchScope>(lDAPSearchScope), 140 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute, 141 userNameAttribute, *this); 142 } 143 else 144 { 145 ADConfigPtr.reset(nullptr); 146 objPath = ADDbusObjectPath; 147 ADConfigPtr = std::make_unique<Config>( 148 bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(), 149 tlsCertFile.c_str(), secureLDAP, lDAPServerURI, lDAPBindDN, 150 lDAPBaseDN, std::move(lDAPBindDNPassword), 151 static_cast<ConfigIface::SearchScope>(lDAPSearchScope), 152 static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute, 153 userNameAttribute, *this); 154 } 155 restartService(nscdService); 156 return objPath; 157 } 158 159 void ConfigMgr::createDefaultObjects() 160 { 161 if (!openLDAPConfigPtr) 162 { 163 openLDAPConfigPtr = std::make_unique<Config>( 164 bus, openLDAPDbusObjectPath.c_str(), configFilePath.c_str(), 165 tlsCacertFile.c_str(), tlsCertFile.c_str(), 166 ConfigIface::Type::OpenLdap, *this); 167 openLDAPConfigPtr->emit_object_added(); 168 } 169 if (!ADConfigPtr) 170 { 171 ADConfigPtr = std::make_unique<Config>( 172 bus, ADDbusObjectPath.c_str(), configFilePath.c_str(), 173 tlsCacertFile.c_str(), tlsCertFile.c_str(), 174 ConfigIface::Type::ActiveDirectory, *this); 175 ADConfigPtr->emit_object_added(); 176 } 177 } 178 179 bool ConfigMgr::enableService(Config& config, bool value) 180 { 181 if (value) 182 { 183 if (openLDAPConfigPtr && openLDAPConfigPtr->enabled()) 184 { 185 elog<NotAllowed>(NotAllowedArgument::REASON( 186 "OpenLDAP service is already active")); 187 } 188 if (ADConfigPtr && ADConfigPtr->enabled()) 189 { 190 elog<NotAllowed>(NotAllowedArgument::REASON( 191 "ActiveDirectory service is already active")); 192 } 193 } 194 return config.enableService(value); 195 } 196 197 void ConfigMgr::restore() 198 { 199 createDefaultObjects(); 200 // Restore the ldap config and their mappings 201 if (ADConfigPtr->deserialize()) 202 { 203 // Restore the role mappings 204 ADConfigPtr->restoreRoleMapping(); 205 ADConfigPtr->emit_object_added(); 206 } 207 if (openLDAPConfigPtr->deserialize()) 208 { 209 // Restore the role mappings 210 openLDAPConfigPtr->restoreRoleMapping(); 211 openLDAPConfigPtr->emit_object_added(); 212 } 213 } 214 215 } // namespace ldap 216 } // namespace phosphor 217