xref: /openbmc/phosphor-user-manager/phosphor-ldap-config/ldap_config.hpp (revision e6500a493a156dd58a92b384c77aef2cbd3addac)
1 #pragma once
2 
3 #include "config.h"
4 
5 #include "ldap_mapper_entry.hpp"
6 
7 #include <phosphor-logging/elog-errors.hpp>
8 #include <phosphor-logging/elog.hpp>
9 #include <phosphor-logging/log.hpp>
10 #include <sdbusplus/bus.hpp>
11 #include <sdbusplus/server/object.hpp>
12 #include <xyz/openbmc_project/Common/error.hpp>
13 #include <xyz/openbmc_project/Object/Enable/server.hpp>
14 #include <xyz/openbmc_project/User/Ldap/Config/server.hpp>
15 #include <xyz/openbmc_project/User/Ldap/Create/server.hpp>
16 #include <xyz/openbmc_project/User/PrivilegeMapper/server.hpp>
17 
18 #include <filesystem>
19 #include <set>
20 #include <string>
21 
22 #ifndef SDBUSPP_NEW_CAMELCASE
23 #define ldapBaseDN lDAPBaseDN
24 #define ldapBindDN lDAPBindDN
25 #define ldapBindDNPassword lDAPBindDNPassword
26 #define ldapSearchScope lDAPSearchScope
27 #define ldapServerURI lDAPServerURI
28 #define ldapType lDAPType
29 #endif
30 
31 namespace phosphor
32 {
33 namespace ldap
34 {
35 
36 using namespace phosphor::logging;
37 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
38 using ConfigIface = sdbusplus::xyz::openbmc_project::User::Ldap::server::Config;
39 using EnableIface = sdbusplus::xyz::openbmc_project::Object::server::Enable;
40 using CreateIface = sdbusplus::server::object::object<
41     sdbusplus::xyz::openbmc_project::User::Ldap::server::Create>;
42 namespace fs = std::filesystem;
43 using MapperIface =
44     sdbusplus::xyz::openbmc_project::User::server::PrivilegeMapper;
45 
46 using Ifaces =
47     sdbusplus::server::object::object<ConfigIface, EnableIface, MapperIface>;
48 using ObjectPath = sdbusplus::message::object_path;
49 
50 namespace sdbusRule = sdbusplus::bus::match::rules;
51 
52 class ConfigMgr;
53 class MockConfigMgr;
54 
55 /** @class Config
56  *  @brief Configuration for LDAP.
57  *  @details concrete implementation of xyz.openbmc_project.User.Ldap.Config
58  *  API, in order to provide LDAP configuration.
59  */
60 class Config : public Ifaces
61 {
62   public:
63     Config() = delete;
64     ~Config() = default;
65     Config(const Config&) = delete;
66     Config& operator=(const Config&) = delete;
67     Config(Config&&) = default;
68     Config& operator=(Config&&) = default;
69 
70     /** @brief Constructor to put object onto bus at a D-Bus path.
71      *  @param[in] bus - Bus to attach to.
72      *  @param[in] path - The D-Bus object path to attach at.
73      *  @param[in] filePath - LDAP configuration file.
74      *  @param[in] caCertFile - LDAP's CA certificate file.
75      *  @param[in] certFile - LDAP's client certificate file.
76      *  @param[in] secureLDAP - Specifies whether to use SSL or not.
77      *  @param[in] ldapServerURI - LDAP URI of the server.
78      *  @param[in] ldapBindDN - distinguished name with which to bind.
79      *  @param[in] ldapBaseDN -  distinguished name to use as search base.
80      *  @param[in] ldapBindDNPassword - credentials with which to bind.
81      *  @param[in] ldapSearchScope - the search scope.
82      *  @param[in] ldapType - Specifies the LDAP server type which can be AD
83      *              or openLDAP.
84      *  @param[in] ldapServiceEnabled - Specifies whether the service would be
85      *  enabled or not.
86      *  @param[in] groupNameAttribute - Specifies attribute name that contains
87      *             the name of the Group in the LDAP server.
88      *  @param[in] userNameAttribute - Specifies attribute name that contains
89      *             the username in the LDAP server.
90      *
91      *  @param[in] parent - parent of config object.
92      */
93 
94     Config(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
95            const char* caCertFile, const char* certFile, bool secureLDAP,
96            std::string ldapServerURI, std::string ldapBindDN,
97            std::string ldapBaseDN, std::string&& ldapBindDNPassword,
98            ConfigIface::SearchScope ldapSearchScope, ConfigIface::Type ldapType,
99            bool ldapServiceEnabled, std::string groupNameAttribute,
100            std::string userNameAttribute, ConfigMgr& parent);
101 
102     /** @brief Constructor to put object onto bus at a D-Bus path.
103      *  @param[in] bus - Bus to attach to.
104      *  @param[in] path - The D-Bus object path to attach at.
105      *  @param[in] filePath - LDAP configuration file.
106      *  @param[in] ldapType - Specifies the LDAP server type which can be AD
107      *              or openLDAP.
108      *  @param[in] parent - parent of config object.
109      */
110     Config(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
111            const char* caCertFile, const char* certFile,
112            ConfigIface::Type ldapType, ConfigMgr& parent);
113 
114     using ConfigIface::groupNameAttribute;
115     using ConfigIface::ldapBaseDN;
116     using ConfigIface::ldapBindDN;
117     using ConfigIface::ldapBindDNPassword;
118     using ConfigIface::ldapSearchScope;
119     using ConfigIface::ldapServerURI;
120     using ConfigIface::ldapType;
121     using ConfigIface::setPropertyByName;
122     using ConfigIface::userNameAttribute;
123     using EnableIface::enabled;
124 
125     /** @brief Update the Server URI property.
126      *  @param[in] value - ldapServerURI value to be updated.
127      *  @returns value of changed ldapServerURI.
128      */
129     std::string ldapServerURI(std::string value) override;
130 
131     /** @brief Update the BindDN property.
132      *  @param[in] value - ldapBindDN value to be updated.
133      *  @returns value of changed ldapBindDN.
134      */
135     std::string ldapBindDN(std::string value) override;
136 
137     /** @brief Update the BaseDN property.
138      *  @param[in] value - ldapBaseDN value to be updated.
139      *  @returns value of changed ldapBaseDN.
140      */
141     std::string ldapBaseDN(std::string value) override;
142 
143     /** @brief Update the Search scope property.
144      *  @param[in] value - ldapSearchScope value to be updated.
145      *  @returns value of changed ldapSearchScope.
146      */
147     ConfigIface::SearchScope
148         ldapSearchScope(ConfigIface::SearchScope value) override;
149 
150     /** @brief Update the LDAP Type property.
151      *  @param[in] value - ldapType value to be updated.
152      *  @returns value of changed ldapType.
153      */
154     ConfigIface::Type ldapType(ConfigIface::Type value) override;
155 
156     /** @brief Update the ldapServiceEnabled property.
157      *  @param[in] value - ldapServiceEnabled value to be updated.
158      *  @returns value of changed ldapServiceEnabled.
159      */
160     bool enabled(bool value) override;
161 
162     /** @brief Update the userNameAttribute property.
163      *  @param[in] value - userNameAttribute value to be updated.
164      *  @returns value of changed userNameAttribute.
165      */
166     std::string userNameAttribute(std::string value) override;
167 
168     /** @brief Update the groupNameAttribute property.
169      *  @param[in] value - groupNameAttribute value to be updated.
170      *  @returns value of changed groupNameAttribute.
171      */
172     std::string groupNameAttribute(std::string value) override;
173 
174     /** @brief Update the BindDNPasword property.
175      *  @param[in] value - ldapBindDNPassword value to be updated.
176      *  @returns value of changed ldapBindDNPassword.
177      */
178     std::string ldapBindDNPassword(std::string value) override;
179 
180     /** @brief Function required by Cereal to perform deserialization.
181      *  @tparam Archive - Cereal archive type (binary in our case).
182      *  @param[in] archive - reference to Cereal archive.
183      *  @param[in] version - Class version that enables handling
184      *                       a serialized data across code levels
185      */
186     template <class Archive>
187     void load(Archive& archive, const std::uint32_t version);
188 
189     /** @brief Function required by Cereal to perform serialization.
190      *  @tparam Archive - Cereal archive type (binary in our case).
191      *  @param[in] archive - reference to Cereal archive.
192      *  @param[in] version - Class version that enables handling
193      *                       a serialized data across code levels
194      */
195     template <class Archive>
196     void save(Archive& archive, const std::uint32_t version) const;
197 
198     /** @brief Serialize and persist this object at the persist
199      *         location.
200      */
201     void serialize();
202 
203     /** @brief Deserialize LDAP config data from the persistent location
204      *         into this object
205      *  @return bool - true if the deserialization was successful, false
206      *                 otherwise.
207      */
208     bool deserialize();
209 
210     /** @brief enable or disable the service with the given value
211      *  @param[in] value - enable/disble
212      *  @returns value of changed status
213      */
214     bool enableService(bool value);
215 
216     /** @brief Creates a mapping for the group to the privilege
217      *
218      *  @param[in] groupName - Group Name to which the privilege needs to be
219      *                         assigned.
220      *  @param[in] privilege - The privilege role associated with the group.
221      *
222      *  @return On success return the D-Bus object path of the created privilege
223      *          mapper entry.
224      */
225     ObjectPath create(std::string groupName, std::string privilege) override;
226 
227     /** @brief Delete privilege mapping for LDAP group
228      *
229      *  This method deletes the privilege mapping
230      *
231      *  @param[in] id - id of the object which needs to be deleted.
232      */
233     void deletePrivilegeMapper(Id id);
234 
235     /** @brief Check if LDAP group privilege mapping requested is valid
236      *
237      *  Check if the privilege mapping already exists for the LDAP group name
238      *  and group name is empty.
239      *
240      *  @param[in] groupName - LDAP group name
241      *
242      *  @return throw exception if the conditions are not met.
243      */
244     void checkPrivilegeMapper(const std::string& groupName);
245 
246     /** @brief Check if the privilege level is a valid one
247      *
248      *  @param[in] privilege - Privilege level
249      *
250      *  @return throw exception if the conditions are not met.
251      */
252     void checkPrivilegeLevel(const std::string& privilege);
253 
254     /** @brief Construct LDAP mapper entry D-Bus objects from their persisted
255      *         representations.
256      */
257     void restoreRoleMapping();
258 
259   private:
260     bool secureLDAP;
261     std::string ldapBindPassword{};
262     std::string tlsCacertFile{};
263     std::string tlsCertFile{};
264     std::string configFilePath{};
265     std::string objectPath{};
266     std::filesystem::path configPersistPath{};
267 
268     /** @brief Persistent sdbusplus D-Bus bus connection. */
269     sdbusplus::bus::bus& bus;
270 
271     /** @brief Create a new LDAP config file.
272      */
273     virtual void writeConfig();
274 
275     /** @brief reference to config manager object */
276     ConfigMgr& parent;
277 
278     /** @brief Id of the last privilege mapper entry */
279     Id entryId = 0;
280 
281     /** @brief container to hold privilege mapper objects */
282     std::map<Id, std::unique_ptr<LDAPMapperEntry>> PrivilegeMapperList;
283 
284     /** @brief available privileges container */
285     std::set<std::string> privMgr = {
286         "priv-admin",
287         "priv-operator",
288         "priv-user",
289         "priv-noaccess",
290     };
291 
292     /** @brief React to InterfaceAdded signal
293      *  @param[in] msg - sdbusplus message
294      */
295     void certificateInstalled(sdbusplus::message::message& msg);
296     sdbusplus::bus::match_t certificateInstalledSignal;
297 
298     sdbusplus::bus::match_t cacertificateInstalledSignal;
299 
300     /** @brief React to certificate changed signal
301      *  @param[in] msg - sdbusplus message
302      */
303     void certificateChanged(sdbusplus::message::message& msg);
304     sdbusplus::bus::match_t certificateChangedSignal;
305 
306     friend class MockConfigMgr;
307 };
308 
309 } // namespace ldap
310 } // namespace phosphor
311