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