Change the name of the files to make it align with other filenames

TestedBy: Unit-Tested

Signed-off-by: Ratan Gupta <ratagupt@linux.vnet.ibm.com>
Change-Id: I657962e8cb06b083877321e27cd0c94644e1ebcb
diff --git a/phosphor-ldap-config/ldap_config.cpp b/phosphor-ldap-config/ldap_config.cpp
new file mode 100644
index 0000000..d10a711
--- /dev/null
+++ b/phosphor-ldap-config/ldap_config.cpp
@@ -0,0 +1,486 @@
+#include "ldap_config_mgr.hpp"
+#include "ldap_config.hpp"
+#include "ldap_config_serialize.hpp"
+#include "utils.hpp"
+#include <filesystem>
+#include <fstream>
+#include <sstream>
+
+namespace phosphor
+{
+namespace ldap
+{
+
+constexpr auto nslcdService = "nslcd.service";
+constexpr auto nscdService = "nscd.service";
+constexpr auto LDAPscheme = "ldap";
+constexpr auto LDAPSscheme = "ldaps";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+namespace fs = std::filesystem;
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
+
+using Line = std::string;
+using Key = std::string;
+using Val = std::string;
+using ConfigInfo = std::map<Key, Val>;
+
+Config::Config(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
+               const char* caCertFile, bool secureLDAP,
+               std::string lDAPServerURI, std::string lDAPBindDN,
+               std::string lDAPBaseDN, std::string&& lDAPBindDNPassword,
+               ConfigIface::SearchScope lDAPSearchScope,
+               ConfigIface::Type lDAPType, bool lDAPServiceEnabled,
+               std::string userNameAttr, std::string groupNameAttr,
+               ConfigMgr& parent) :
+    Ifaces(bus, path, true),
+    secureLDAP(secureLDAP), lDAPBindPassword(std::move(lDAPBindDNPassword)),
+    configFilePath(filePath), tlsCacertFile(caCertFile), bus(bus),
+    parent(parent)
+{
+    ConfigIface::lDAPServerURI(lDAPServerURI);
+    ConfigIface::lDAPBindDN(lDAPBindDN);
+    ConfigIface::lDAPBaseDN(lDAPBaseDN);
+    ConfigIface::lDAPSearchScope(lDAPSearchScope);
+    ConfigIface::lDAPType(lDAPType);
+    EnableIface::enabled(lDAPServiceEnabled);
+    ConfigIface::userNameAttribute(userNameAttr);
+    ConfigIface::groupNameAttribute(groupNameAttr);
+    // Don't update the bindDN password under ConfigIface::
+    writeConfig();
+    // Emit deferred signal.
+    this->emit_object_added();
+    parent.startOrStopService(nslcdService, enabled());
+}
+
+void Config::delete_()
+{
+    parent.deleteObject();
+    try
+    {
+        fs::path configDir = fs::path(configFilePath.c_str()).parent_path();
+
+        fs::copy_file(configDir / defaultNslcdFile, LDAP_CONFIG_FILE,
+                      fs::copy_options::overwrite_existing);
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>("Failed to rename Config Files while deleting Object",
+                        entry("ERR=%s", e.what()));
+        elog<InternalFailure>();
+    }
+
+    parent.restartService(nscdService);
+    parent.stopService(nslcdService);
+}
+
+void Config::writeConfig()
+{
+    std::stringstream confData;
+    auto isPwdTobeWritten = false;
+    std::string userNameAttr;
+
+    confData << "uid root\n";
+    confData << "gid root\n\n";
+    confData << "ldap_version 3\n\n";
+    confData << "timelimit 30\n";
+    confData << "bind_timelimit 30\n";
+    confData << "pagesize 1000\n";
+    confData << "referrals off\n\n";
+    confData << "uri " << lDAPServerURI() << "\n\n";
+    confData << "base " << lDAPBaseDN() << "\n\n";
+    confData << "binddn " << lDAPBindDN() << "\n";
+    if (!lDAPBindPassword.empty())
+    {
+        confData << "bindpw " << lDAPBindPassword << "\n";
+        isPwdTobeWritten = true;
+    }
+    confData << "\n";
+    switch (lDAPSearchScope())
+    {
+        case ConfigIface::SearchScope::sub:
+            confData << "scope sub\n\n";
+            break;
+        case ConfigIface::SearchScope::one:
+            confData << "scope one\n\n";
+            break;
+        case ConfigIface::SearchScope::base:
+            confData << "scope base\n\n";
+            break;
+    }
+    confData << "base passwd " << lDAPBaseDN() << "\n";
+    confData << "base shadow " << lDAPBaseDN() << "\n\n";
+    if (secureLDAP == true)
+    {
+        confData << "ssl on\n";
+        confData << "tls_reqcert hard\n";
+        confData << "tls_cacertFile " << tlsCacertFile.c_str() << "\n";
+    }
+    else
+    {
+        confData << "ssl off\n";
+    }
+    confData << "\n";
+    if (lDAPType() == ConfigIface::Type::ActiveDirectory)
+    {
+        if (ConfigIface::userNameAttribute().empty())
+        {
+            ConfigIface::userNameAttribute("sAMAccountName");
+        }
+        if (ConfigIface::groupNameAttribute().empty())
+        {
+            ConfigIface::groupNameAttribute("primaryGroupID");
+        }
+        confData << "filter passwd (&(objectClass=user)(objectClass=person)"
+                    "(!(objectClass=computer)))\n";
+        confData
+            << "filter group (|(objectclass=group)(objectclass=groupofnames) "
+               "(objectclass=groupofuniquenames))\n";
+        confData << "map passwd uid              "
+                 << ConfigIface::userNameAttribute() << "\n";
+        confData << "map passwd uidNumber        "
+                    "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
+        confData << "map passwd gidNumber        "
+                 << ConfigIface::groupNameAttribute() << "\n";
+        confData << "map passwd homeDirectory    \"/home/$sAMAccountName\"\n";
+        confData << "map passwd gecos            displayName\n";
+        confData << "map passwd loginShell       \"/bin/bash\"\n";
+        confData << "map group gidNumber         "
+                    "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
+        confData << "map group cn                "
+                 << ConfigIface::userNameAttribute() << "\n";
+    }
+    else if (lDAPType() == ConfigIface::Type::OpenLdap)
+    {
+        if (ConfigIface::userNameAttribute().empty())
+        {
+            ConfigIface::userNameAttribute("cn");
+        }
+        if (ConfigIface::groupNameAttribute().empty())
+        {
+            ConfigIface::groupNameAttribute("gidNumber");
+        }
+        confData << "filter passwd (objectclass=*)\n";
+        confData << "map passwd gecos displayName\n";
+        confData << "filter group (objectclass=posixGroup)\n";
+        confData << "map passwd uid              "
+                 << ConfigIface::userNameAttribute() << "\n";
+        confData << "map passwd gidNumber        "
+                 << ConfigIface::groupNameAttribute() << "\n";
+    }
+    try
+    {
+        std::fstream stream(configFilePath.c_str(), std::fstream::out);
+        // remove the read permission from others if password is being written.
+        // nslcd forces this behaviour.
+        auto permission = fs::perms::owner_read | fs::perms::owner_write |
+                          fs::perms::group_read;
+        if (isPwdTobeWritten)
+        {
+            fs::permissions(configFilePath, permission);
+        }
+        else
+        {
+            fs::permissions(configFilePath,
+                            permission | fs::perms::others_read);
+        }
+
+        stream << confData.str();
+        stream.flush();
+        stream.close();
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return;
+}
+
+std::string Config::lDAPBindDNPassword(std::string value)
+{
+    // Don't update the D-bus object, this is just to
+    // facilitate if user wants to change the bind dn password
+    // once d-bus object gets created.
+    lDAPBindPassword = value;
+    try
+    {
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return value;
+}
+
+std::string Config::lDAPServerURI(std::string value)
+{
+    std::string val;
+    try
+    {
+        if (value == lDAPServerURI())
+        {
+            return value;
+        }
+        if (isValidLDAPURI(value, LDAPSscheme))
+        {
+            secureLDAP = true;
+        }
+        else if (isValidLDAPURI(value, LDAPscheme))
+        {
+            secureLDAP = false;
+        }
+        else
+        {
+            log<level::ERR>("bad LDAP Server URI",
+                            entry("LDAPSERVERURI=%s", value.c_str()));
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
+                                  Argument::ARGUMENT_VALUE(value.c_str()));
+        }
+
+        if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
+        {
+            log<level::ERR>("LDAP server's CA certificate not provided",
+                            entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
+            elog<NoCACertificate>();
+        }
+        val = ConfigIface::lDAPServerURI(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const InvalidArgument& e)
+    {
+        throw;
+    }
+    catch (const NoCACertificate& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+std::string Config::lDAPBindDN(std::string value)
+{
+    std::string val;
+    try
+    {
+        if (value == lDAPBindDN())
+        {
+            return value;
+        }
+
+        if (value.empty())
+        {
+            log<level::ERR>("Not a valid LDAP BINDDN",
+                            entry("LDAPBINDDN=%s", value.c_str()));
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBindDN"),
+                                  Argument::ARGUMENT_VALUE(value.c_str()));
+        }
+
+        val = ConfigIface::lDAPBindDN(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const InvalidArgument& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+std::string Config::lDAPBaseDN(std::string value)
+{
+    std::string val;
+    try
+    {
+        if (value == lDAPBaseDN())
+        {
+            return value;
+        }
+
+        if (value.empty())
+        {
+            log<level::ERR>("Not a valid LDAP BASEDN",
+                            entry("BASEDN=%s", value.c_str()));
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPBaseDN"),
+                                  Argument::ARGUMENT_VALUE(value.c_str()));
+        }
+
+        val = ConfigIface::lDAPBaseDN(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const InvalidArgument& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+ConfigIface::SearchScope Config::lDAPSearchScope(ConfigIface::SearchScope value)
+{
+    ConfigIface::SearchScope val;
+    try
+    {
+        if (value == lDAPSearchScope())
+        {
+            return value;
+        }
+
+        val = ConfigIface::lDAPSearchScope(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+ConfigIface::Type Config::lDAPType(ConfigIface::Type value)
+{
+    ConfigIface::Type val;
+    try
+    {
+        if (value == lDAPType())
+        {
+            return value;
+        }
+
+        val = ConfigIface::lDAPType(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+bool Config::enabled(bool value)
+{
+    bool isEnable;
+    try
+    {
+        if (value == enabled())
+        {
+            return value;
+        }
+        isEnable = EnableIface::enabled(value);
+        // save the enabled property.
+        serialize(*this, parent.dbusPersistentPath);
+        parent.startOrStopService(nslcdService, value);
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return isEnable;
+}
+
+std::string Config::userNameAttribute(std::string value)
+{
+    std::string val;
+    try
+    {
+        if (value == userNameAttribute())
+        {
+            return value;
+        }
+
+        val = ConfigIface::userNameAttribute(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+std::string Config::groupNameAttribute(std::string value)
+{
+    std::string val;
+    try
+    {
+        if (value == groupNameAttribute())
+        {
+            return value;
+        }
+
+        val = ConfigIface::groupNameAttribute(value);
+        writeConfig();
+        parent.startOrStopService(nslcdService, enabled());
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+    return val;
+}
+
+} // namespace ldap
+} // namespace phosphor