| Lewanczyk, Dawid | 88d16c9 | 2018-02-02 14:51:09 +0100 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 | #pragma once | 
| Lewanczyk, Dawid | 88d16c9 | 2018-02-02 14:51:09 +0100 | [diff] [blame] | 17 |  | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 18 | #include "generated/enums/account_service.hpp" | 
 | 19 | #include "registries/privilege_registry.hpp" | 
 | 20 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 21 | #include <app.hpp> | 
| Ratan Gupta | 24c8542 | 2019-01-30 19:41:24 +0530 | [diff] [blame] | 22 | #include <dbus_utility.hpp> | 
| Ed Tanous | 65b0dc3 | 2018-09-19 16:04:03 -0700 | [diff] [blame] | 23 | #include <error_messages.hpp> | 
| Ed Tanous | b9b2e0b | 2018-09-13 13:47:50 -0700 | [diff] [blame] | 24 | #include <openbmc_dbus_rest.hpp> | 
| Ed Tanous | 52cc112 | 2020-07-18 13:51:21 -0700 | [diff] [blame] | 25 | #include <persistent_data.hpp> | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 26 | #include <query.hpp> | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 27 | #include <sdbusplus/asio/property.hpp> | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 28 | #include <sdbusplus/unpack_properties.hpp> | 
 | 29 | #include <utils/dbus_utils.hpp> | 
| Ed Tanous | a840879 | 2018-09-05 16:08:38 -0700 | [diff] [blame] | 30 | #include <utils/json_utils.hpp> | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 31 |  | 
| Abhishek Patel | c722981 | 2022-02-01 10:07:15 -0600 | [diff] [blame] | 32 | #include <optional> | 
 | 33 | #include <string> | 
 | 34 | #include <vector> | 
 | 35 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 36 | namespace redfish | 
 | 37 | { | 
| Lewanczyk, Dawid | 88d16c9 | 2018-02-02 14:51:09 +0100 | [diff] [blame] | 38 |  | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 39 | constexpr const char* ldapConfigObjectName = | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 40 |     "/xyz/openbmc_project/user/ldap/openldap"; | 
| Ed Tanous | 2c70f80 | 2020-09-28 14:29:23 -0700 | [diff] [blame] | 41 | constexpr const char* adConfigObject = | 
| Ratan Gupta | ab828d7 | 2019-04-22 14:18:33 +0530 | [diff] [blame] | 42 |     "/xyz/openbmc_project/user/ldap/active_directory"; | 
 | 43 |  | 
| P Dheeraj Srujan Kumar | b477fd4 | 2021-12-16 07:17:51 +0530 | [diff] [blame] | 44 | constexpr const char* rootUserDbusPath = "/xyz/openbmc_project/user/"; | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 45 | constexpr const char* ldapRootObject = "/xyz/openbmc_project/user/ldap"; | 
 | 46 | constexpr const char* ldapDbusService = "xyz.openbmc_project.Ldap.Config"; | 
 | 47 | constexpr const char* ldapConfigInterface = | 
 | 48 |     "xyz.openbmc_project.User.Ldap.Config"; | 
 | 49 | constexpr const char* ldapCreateInterface = | 
 | 50 |     "xyz.openbmc_project.User.Ldap.Create"; | 
 | 51 | constexpr const char* ldapEnableInterface = "xyz.openbmc_project.Object.Enable"; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 52 | constexpr const char* ldapPrivMapperInterface = | 
 | 53 |     "xyz.openbmc_project.User.PrivilegeMapper"; | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 54 | constexpr const char* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager"; | 
 | 55 | constexpr const char* propertyInterface = "org.freedesktop.DBus.Properties"; | 
 | 56 | constexpr const char* mapperBusName = "xyz.openbmc_project.ObjectMapper"; | 
 | 57 | constexpr const char* mapperObjectPath = "/xyz/openbmc_project/object_mapper"; | 
 | 58 | constexpr const char* mapperIntf = "xyz.openbmc_project.ObjectMapper"; | 
 | 59 |  | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 60 | struct LDAPRoleMapData | 
 | 61 | { | 
 | 62 |     std::string groupName; | 
 | 63 |     std::string privilege; | 
 | 64 | }; | 
 | 65 |  | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 66 | struct LDAPConfigData | 
 | 67 | { | 
 | 68 |     std::string uri{}; | 
 | 69 |     std::string bindDN{}; | 
 | 70 |     std::string baseDN{}; | 
 | 71 |     std::string searchScope{}; | 
 | 72 |     std::string serverType{}; | 
 | 73 |     bool serviceEnabled = false; | 
 | 74 |     std::string userNameAttribute{}; | 
 | 75 |     std::string groupAttribute{}; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 76 |     std::vector<std::pair<std::string, LDAPRoleMapData>> groupRoleList; | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 77 | }; | 
 | 78 |  | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 79 | inline std::string getRoleIdFromPrivilege(std::string_view role) | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 80 | { | 
 | 81 |     if (role == "priv-admin") | 
 | 82 |     { | 
 | 83 |         return "Administrator"; | 
 | 84 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 85 |     if (role == "priv-user") | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 86 |     { | 
| AppaRao Puli | c80fee5 | 2019-10-16 14:49:36 +0530 | [diff] [blame] | 87 |         return "ReadOnly"; | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 88 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 89 |     if (role == "priv-operator") | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 90 |     { | 
 | 91 |         return "Operator"; | 
 | 92 |     } | 
 | 93 |     return ""; | 
 | 94 | } | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 95 | inline std::string getPrivilegeFromRoleId(std::string_view role) | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 96 | { | 
 | 97 |     if (role == "Administrator") | 
 | 98 |     { | 
 | 99 |         return "priv-admin"; | 
 | 100 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 101 |     if (role == "ReadOnly") | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 102 |     { | 
 | 103 |         return "priv-user"; | 
 | 104 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 105 |     if (role == "Operator") | 
| AppaRao Puli | 84e12cb | 2018-10-11 01:28:15 +0530 | [diff] [blame] | 106 |     { | 
 | 107 |         return "priv-operator"; | 
 | 108 |     } | 
 | 109 |     return ""; | 
 | 110 | } | 
| Ed Tanous | b9b2e0b | 2018-09-13 13:47:50 -0700 | [diff] [blame] | 111 |  | 
| Abhishek Patel | c722981 | 2022-02-01 10:07:15 -0600 | [diff] [blame] | 112 | /** | 
 | 113 |  * @brief Maps user group names retrieved from D-Bus object to | 
 | 114 |  * Account Types. | 
 | 115 |  * | 
 | 116 |  * @param[in] userGroups List of User groups | 
 | 117 |  * @param[out] res AccountTypes populated | 
 | 118 |  * | 
 | 119 |  * @return true in case of success, false if UserGroups contains | 
 | 120 |  * invalid group name(s). | 
 | 121 |  */ | 
 | 122 | inline bool translateUserGroup(const std::vector<std::string>& userGroups, | 
 | 123 |                                crow::Response& res) | 
 | 124 | { | 
 | 125 |     std::vector<std::string> accountTypes; | 
 | 126 |     for (const auto& userGroup : userGroups) | 
 | 127 |     { | 
 | 128 |         if (userGroup == "redfish") | 
 | 129 |         { | 
 | 130 |             accountTypes.emplace_back("Redfish"); | 
 | 131 |             accountTypes.emplace_back("WebUI"); | 
 | 132 |         } | 
 | 133 |         else if (userGroup == "ipmi") | 
 | 134 |         { | 
 | 135 |             accountTypes.emplace_back("IPMI"); | 
 | 136 |         } | 
 | 137 |         else if (userGroup == "ssh") | 
 | 138 |         { | 
 | 139 |             accountTypes.emplace_back("HostConsole"); | 
 | 140 |             accountTypes.emplace_back("ManagerConsole"); | 
 | 141 |         } | 
 | 142 |         else if (userGroup == "web") | 
 | 143 |         { | 
 | 144 |             // 'web' is one of the valid groups in the UserGroups property of | 
 | 145 |             // the user account in the D-Bus object. This group is currently not | 
 | 146 |             // doing anything, and is considered to be equivalent to 'redfish'. | 
 | 147 |             // 'redfish' user group is mapped to 'Redfish'and 'WebUI' | 
 | 148 |             // AccountTypes, so do nothing here... | 
 | 149 |         } | 
 | 150 |         else | 
 | 151 |         { | 
 | 152 |             // Invalid user group name. Caller throws an excption. | 
 | 153 |             return false; | 
 | 154 |         } | 
 | 155 |     } | 
 | 156 |  | 
 | 157 |     res.jsonValue["AccountTypes"] = std::move(accountTypes); | 
 | 158 |     return true; | 
 | 159 | } | 
 | 160 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 161 | inline void userErrorMessageHandler( | 
 | 162 |     const sd_bus_error* e, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 163 |     const std::string& newUser, const std::string& username) | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 164 | { | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 165 |     if (e == nullptr) | 
 | 166 |     { | 
 | 167 |         messages::internalError(asyncResp->res); | 
 | 168 |         return; | 
 | 169 |     } | 
 | 170 |  | 
| Manojkiran Eda | 055806b | 2020-11-03 09:36:28 +0530 | [diff] [blame] | 171 |     const char* errorMessage = e->name; | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 172 |     if (strcmp(errorMessage, | 
 | 173 |                "xyz.openbmc_project.User.Common.Error.UserNameExists") == 0) | 
 | 174 |     { | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 175 |         messages::resourceAlreadyExists(asyncResp->res, "ManagerAccount", | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 176 |                                         "UserName", newUser); | 
 | 177 |     } | 
 | 178 |     else if (strcmp(errorMessage, "xyz.openbmc_project.User.Common.Error." | 
 | 179 |                                   "UserNameDoesNotExist") == 0) | 
 | 180 |     { | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 181 |         messages::resourceNotFound(asyncResp->res, "ManagerAccount", username); | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 182 |     } | 
| Ed Tanous | d4d2579 | 2020-09-29 15:15:03 -0700 | [diff] [blame] | 183 |     else if ((strcmp(errorMessage, | 
 | 184 |                      "xyz.openbmc_project.Common.Error.InvalidArgument") == | 
 | 185 |               0) || | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 186 |              (strcmp( | 
 | 187 |                   errorMessage, | 
 | 188 |                   "xyz.openbmc_project.User.Common.Error.UserNameGroupFail") == | 
 | 189 |               0)) | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 190 |     { | 
 | 191 |         messages::propertyValueFormatError(asyncResp->res, newUser, "UserName"); | 
 | 192 |     } | 
 | 193 |     else if (strcmp(errorMessage, | 
 | 194 |                     "xyz.openbmc_project.User.Common.Error.NoResource") == 0) | 
 | 195 |     { | 
 | 196 |         messages::createLimitReachedForResource(asyncResp->res); | 
 | 197 |     } | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 198 |     else | 
 | 199 |     { | 
 | 200 |         messages::internalError(asyncResp->res); | 
 | 201 |     } | 
| jayaprakash Mutyala | 66b5ca7 | 2019-08-07 20:26:37 +0000 | [diff] [blame] | 202 | } | 
 | 203 |  | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 204 | inline void parseLDAPConfigData(nlohmann::json& jsonResponse, | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 205 |                                 const LDAPConfigData& confData, | 
 | 206 |                                 const std::string& ldapType) | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 207 | { | 
| Ratan Gupta | ab828d7 | 2019-04-22 14:18:33 +0530 | [diff] [blame] | 208 |     std::string service = | 
 | 209 |         (ldapType == "LDAP") ? "LDAPService" : "ActiveDirectoryService"; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 210 |  | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 211 |     nlohmann::json& ldap = jsonResponse[ldapType]; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 212 |  | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 213 |     ldap["ServiceEnabled"] = confData.serviceEnabled; | 
 | 214 |     ldap["ServiceAddresses"] = nlohmann::json::array({confData.uri}); | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 215 |     ldap["Authentication"]["AuthenticationType"] = | 
 | 216 |         account_service::AuthenticationTypes::UsernameAndPassword; | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 217 |     ldap["Authentication"]["Username"] = confData.bindDN; | 
 | 218 |     ldap["Authentication"]["Password"] = nullptr; | 
 | 219 |  | 
 | 220 |     ldap["LDAPService"]["SearchSettings"]["BaseDistinguishedNames"] = | 
 | 221 |         nlohmann::json::array({confData.baseDN}); | 
 | 222 |     ldap["LDAPService"]["SearchSettings"]["UsernameAttribute"] = | 
 | 223 |         confData.userNameAttribute; | 
 | 224 |     ldap["LDAPService"]["SearchSettings"]["GroupsAttribute"] = | 
 | 225 |         confData.groupAttribute; | 
 | 226 |  | 
 | 227 |     nlohmann::json& roleMapArray = ldap["RemoteRoleMapping"]; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 228 |     roleMapArray = nlohmann::json::array(); | 
| Ed Tanous | 9eb808c | 2022-01-25 10:19:23 -0800 | [diff] [blame] | 229 |     for (const auto& obj : confData.groupRoleList) | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 230 |     { | 
 | 231 |         BMCWEB_LOG_DEBUG << "Pushing the data groupName=" | 
 | 232 |                          << obj.second.groupName << "\n"; | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 233 |  | 
 | 234 |         nlohmann::json::array_t remoteGroupArray; | 
 | 235 |         nlohmann::json::object_t remoteGroup; | 
 | 236 |         remoteGroup["RemoteGroup"] = obj.second.groupName; | 
 | 237 |         remoteGroupArray.emplace_back(std::move(remoteGroup)); | 
 | 238 |         roleMapArray.emplace_back(std::move(remoteGroupArray)); | 
 | 239 |  | 
 | 240 |         nlohmann::json::array_t localRoleArray; | 
 | 241 |         nlohmann::json::object_t localRole; | 
 | 242 |         localRole["LocalRole"] = getRoleIdFromPrivilege(obj.second.privilege); | 
 | 243 |         localRoleArray.emplace_back(std::move(localRole)); | 
 | 244 |         roleMapArray.emplace_back(std::move(localRoleArray)); | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 245 |     } | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 246 | } | 
 | 247 |  | 
 | 248 | /** | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 249 |  *  @brief validates given JSON input and then calls appropriate method to | 
 | 250 |  * create, to delete or to set Rolemapping object based on the given input. | 
 | 251 |  * | 
 | 252 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 253 | inline void handleRoleMapPatch( | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 254 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 255 |     const std::vector<std::pair<std::string, LDAPRoleMapData>>& roleMapObjData, | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 256 |     const std::string& serverType, const std::vector<nlohmann::json>& input) | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 257 | { | 
 | 258 |     for (size_t index = 0; index < input.size(); index++) | 
 | 259 |     { | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 260 |         const nlohmann::json& thisJson = input[index]; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 261 |  | 
 | 262 |         if (thisJson.is_null()) | 
 | 263 |         { | 
 | 264 |             // delete the existing object | 
 | 265 |             if (index < roleMapObjData.size()) | 
 | 266 |             { | 
 | 267 |                 crow::connections::systemBus->async_method_call( | 
 | 268 |                     [asyncResp, roleMapObjData, serverType, | 
 | 269 |                      index](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 270 |                     if (ec) | 
 | 271 |                     { | 
 | 272 |                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec; | 
 | 273 |                         messages::internalError(asyncResp->res); | 
 | 274 |                         return; | 
 | 275 |                     } | 
 | 276 |                     asyncResp->res | 
 | 277 |                         .jsonValue[serverType]["RemoteRoleMapping"][index] = | 
 | 278 |                         nullptr; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 279 |                     }, | 
 | 280 |                     ldapDbusService, roleMapObjData[index].first, | 
 | 281 |                     "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 282 |             } | 
 | 283 |             else | 
 | 284 |             { | 
 | 285 |                 BMCWEB_LOG_ERROR << "Can't delete the object"; | 
 | 286 |                 messages::propertyValueTypeError( | 
| Ed Tanous | 71f52d9 | 2021-02-19 08:51:17 -0800 | [diff] [blame] | 287 |                     asyncResp->res, | 
 | 288 |                     thisJson.dump(2, ' ', true, | 
 | 289 |                                   nlohmann::json::error_handler_t::replace), | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 290 |                     "RemoteRoleMapping/" + std::to_string(index)); | 
 | 291 |                 return; | 
 | 292 |             } | 
 | 293 |         } | 
 | 294 |         else if (thisJson.empty()) | 
 | 295 |         { | 
 | 296 |             // Don't do anything for the empty objects,parse next json | 
 | 297 |             // eg {"RemoteRoleMapping",[{}]} | 
 | 298 |         } | 
 | 299 |         else | 
 | 300 |         { | 
 | 301 |             // update/create the object | 
 | 302 |             std::optional<std::string> remoteGroup; | 
 | 303 |             std::optional<std::string> localRole; | 
 | 304 |  | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 305 |             // This is a copy, but it's required in this case because of how | 
 | 306 |             // readJson is structured | 
 | 307 |             nlohmann::json thisJsonCopy = thisJson; | 
 | 308 |             if (!json_util::readJson(thisJsonCopy, asyncResp->res, | 
 | 309 |                                      "RemoteGroup", remoteGroup, "LocalRole", | 
 | 310 |                                      localRole)) | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 311 |             { | 
 | 312 |                 continue; | 
 | 313 |             } | 
 | 314 |  | 
 | 315 |             // Update existing RoleMapping Object | 
 | 316 |             if (index < roleMapObjData.size()) | 
 | 317 |             { | 
 | 318 |                 BMCWEB_LOG_DEBUG << "Update Role Map Object"; | 
 | 319 |                 // If "RemoteGroup" info is provided | 
 | 320 |                 if (remoteGroup) | 
 | 321 |                 { | 
 | 322 |                     crow::connections::systemBus->async_method_call( | 
 | 323 |                         [asyncResp, roleMapObjData, serverType, index, | 
 | 324 |                          remoteGroup](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 325 |                         if (ec) | 
 | 326 |                         { | 
 | 327 |                             BMCWEB_LOG_ERROR << "DBUS response error: " << ec; | 
 | 328 |                             messages::internalError(asyncResp->res); | 
 | 329 |                             return; | 
 | 330 |                         } | 
 | 331 |                         asyncResp->res | 
 | 332 |                             .jsonValue[serverType]["RemoteRoleMapping"][index] | 
 | 333 |                                       ["RemoteGroup"] = *remoteGroup; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 334 |                         }, | 
 | 335 |                         ldapDbusService, roleMapObjData[index].first, | 
 | 336 |                         propertyInterface, "Set", | 
 | 337 |                         "xyz.openbmc_project.User.PrivilegeMapperEntry", | 
 | 338 |                         "GroupName", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 339 |                         dbus::utility::DbusVariantType( | 
 | 340 |                             std::move(*remoteGroup))); | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 341 |                 } | 
 | 342 |  | 
 | 343 |                 // If "LocalRole" info is provided | 
 | 344 |                 if (localRole) | 
 | 345 |                 { | 
 | 346 |                     crow::connections::systemBus->async_method_call( | 
 | 347 |                         [asyncResp, roleMapObjData, serverType, index, | 
 | 348 |                          localRole](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 349 |                         if (ec) | 
 | 350 |                         { | 
 | 351 |                             BMCWEB_LOG_ERROR << "DBUS response error: " << ec; | 
 | 352 |                             messages::internalError(asyncResp->res); | 
 | 353 |                             return; | 
 | 354 |                         } | 
 | 355 |                         asyncResp->res | 
 | 356 |                             .jsonValue[serverType]["RemoteRoleMapping"][index] | 
 | 357 |                                       ["LocalRole"] = *localRole; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 358 |                         }, | 
 | 359 |                         ldapDbusService, roleMapObjData[index].first, | 
 | 360 |                         propertyInterface, "Set", | 
 | 361 |                         "xyz.openbmc_project.User.PrivilegeMapperEntry", | 
 | 362 |                         "Privilege", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 363 |                         dbus::utility::DbusVariantType( | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 364 |                             getPrivilegeFromRoleId(std::move(*localRole)))); | 
 | 365 |                 } | 
 | 366 |             } | 
 | 367 |             // Create a new RoleMapping Object. | 
 | 368 |             else | 
 | 369 |             { | 
 | 370 |                 BMCWEB_LOG_DEBUG | 
 | 371 |                     << "setRoleMappingProperties: Creating new Object"; | 
 | 372 |                 std::string pathString = | 
 | 373 |                     "RemoteRoleMapping/" + std::to_string(index); | 
 | 374 |  | 
 | 375 |                 if (!localRole) | 
 | 376 |                 { | 
 | 377 |                     messages::propertyMissing(asyncResp->res, | 
 | 378 |                                               pathString + "/LocalRole"); | 
 | 379 |                     continue; | 
 | 380 |                 } | 
 | 381 |                 if (!remoteGroup) | 
 | 382 |                 { | 
 | 383 |                     messages::propertyMissing(asyncResp->res, | 
 | 384 |                                               pathString + "/RemoteGroup"); | 
 | 385 |                     continue; | 
 | 386 |                 } | 
 | 387 |  | 
 | 388 |                 std::string dbusObjectPath; | 
 | 389 |                 if (serverType == "ActiveDirectory") | 
 | 390 |                 { | 
| Ed Tanous | 2c70f80 | 2020-09-28 14:29:23 -0700 | [diff] [blame] | 391 |                     dbusObjectPath = adConfigObject; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 392 |                 } | 
 | 393 |                 else if (serverType == "LDAP") | 
 | 394 |                 { | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 395 |                     dbusObjectPath = ldapConfigObjectName; | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 396 |                 } | 
 | 397 |  | 
 | 398 |                 BMCWEB_LOG_DEBUG << "Remote Group=" << *remoteGroup | 
 | 399 |                                  << ",LocalRole=" << *localRole; | 
 | 400 |  | 
 | 401 |                 crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 402 |                     [asyncResp, serverType, localRole, | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 403 |                      remoteGroup](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 404 |                     if (ec) | 
 | 405 |                     { | 
 | 406 |                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec; | 
 | 407 |                         messages::internalError(asyncResp->res); | 
 | 408 |                         return; | 
 | 409 |                     } | 
 | 410 |                     nlohmann::json& remoteRoleJson = | 
 | 411 |                         asyncResp->res | 
 | 412 |                             .jsonValue[serverType]["RemoteRoleMapping"]; | 
 | 413 |                     nlohmann::json::object_t roleMapEntry; | 
 | 414 |                     roleMapEntry["LocalRole"] = *localRole; | 
 | 415 |                     roleMapEntry["RemoteGroup"] = *remoteGroup; | 
 | 416 |                     remoteRoleJson.push_back(std::move(roleMapEntry)); | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 417 |                     }, | 
 | 418 |                     ldapDbusService, dbusObjectPath, ldapPrivMapperInterface, | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 419 |                     "Create", *remoteGroup, | 
| Ratan Gupta | 0678524 | 2019-07-26 22:30:16 +0530 | [diff] [blame] | 420 |                     getPrivilegeFromRoleId(std::move(*localRole))); | 
 | 421 |             } | 
 | 422 |         } | 
 | 423 |     } | 
 | 424 | } | 
 | 425 |  | 
 | 426 | /** | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 427 |  * Function that retrieves all properties for LDAP config object | 
 | 428 |  * into JSON | 
 | 429 |  */ | 
 | 430 | template <typename CallbackFunc> | 
 | 431 | inline void getLDAPConfigData(const std::string& ldapType, | 
 | 432 |                               CallbackFunc&& callback) | 
 | 433 | { | 
| Ratan Gupta | ab828d7 | 2019-04-22 14:18:33 +0530 | [diff] [blame] | 434 |  | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 435 |     const std::array<const char*, 2> interfaces = {ldapEnableInterface, | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 436 |                                                    ldapConfigInterface}; | 
 | 437 |  | 
 | 438 |     crow::connections::systemBus->async_method_call( | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 439 |         [callback, ldapType](const boost::system::error_code ec, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 440 |                              const dbus::utility::MapperGetObject& resp) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 441 |         if (ec || resp.empty()) | 
 | 442 |         { | 
 | 443 |             BMCWEB_LOG_ERROR | 
 | 444 |                 << "DBUS response error during getting of service name: " << ec; | 
 | 445 |             LDAPConfigData empty{}; | 
 | 446 |             callback(false, empty, ldapType); | 
 | 447 |             return; | 
 | 448 |         } | 
 | 449 |         std::string service = resp.begin()->first; | 
 | 450 |         crow::connections::systemBus->async_method_call( | 
 | 451 |             [callback, | 
 | 452 |              ldapType](const boost::system::error_code errorCode, | 
 | 453 |                        const dbus::utility::ManagedObjectType& ldapObjects) { | 
 | 454 |             LDAPConfigData confData{}; | 
 | 455 |             if (errorCode) | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 456 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 457 |                 callback(false, confData, ldapType); | 
 | 458 |                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << errorCode; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 459 |                 return; | 
 | 460 |             } | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 461 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 462 |             std::string ldapDbusType; | 
 | 463 |             std::string searchString; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 464 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 465 |             if (ldapType == "LDAP") | 
 | 466 |             { | 
 | 467 |                 ldapDbusType = | 
 | 468 |                     "xyz.openbmc_project.User.Ldap.Config.Type.OpenLdap"; | 
 | 469 |                 searchString = "openldap"; | 
 | 470 |             } | 
 | 471 |             else if (ldapType == "ActiveDirectory") | 
 | 472 |             { | 
 | 473 |                 ldapDbusType = | 
 | 474 |                     "xyz.openbmc_project.User.Ldap.Config.Type.ActiveDirectory"; | 
 | 475 |                 searchString = "active_directory"; | 
 | 476 |             } | 
 | 477 |             else | 
 | 478 |             { | 
 | 479 |                 BMCWEB_LOG_ERROR << "Can't get the DbusType for the given type=" | 
 | 480 |                                  << ldapType; | 
 | 481 |                 callback(false, confData, ldapType); | 
 | 482 |                 return; | 
 | 483 |             } | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 484 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 485 |             std::string ldapEnableInterfaceStr = ldapEnableInterface; | 
 | 486 |             std::string ldapConfigInterfaceStr = ldapConfigInterface; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 487 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 488 |             for (const auto& object : ldapObjects) | 
 | 489 |             { | 
 | 490 |                 // let's find the object whose ldap type is equal to the | 
 | 491 |                 // given type | 
 | 492 |                 if (object.first.str.find(searchString) == std::string::npos) | 
 | 493 |                 { | 
 | 494 |                     continue; | 
 | 495 |                 } | 
 | 496 |  | 
 | 497 |                 for (const auto& interface : object.second) | 
 | 498 |                 { | 
 | 499 |                     if (interface.first == ldapEnableInterfaceStr) | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 500 |                     { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 501 |                         // rest of the properties are string. | 
 | 502 |                         for (const auto& property : interface.second) | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 503 |                         { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 504 |                             if (property.first == "Enabled") | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 505 |                             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 506 |                                 const bool* value = | 
 | 507 |                                     std::get_if<bool>(&property.second); | 
 | 508 |                                 if (value == nullptr) | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 509 |                                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 510 |                                     continue; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 511 |                                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 512 |                                 confData.serviceEnabled = *value; | 
 | 513 |                                 break; | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 514 |                             } | 
 | 515 |                         } | 
 | 516 |                     } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 517 |                     else if (interface.first == ldapConfigInterfaceStr) | 
 | 518 |                     { | 
 | 519 |  | 
 | 520 |                         for (const auto& property : interface.second) | 
 | 521 |                         { | 
 | 522 |                             const std::string* strValue = | 
 | 523 |                                 std::get_if<std::string>(&property.second); | 
 | 524 |                             if (strValue == nullptr) | 
 | 525 |                             { | 
 | 526 |                                 continue; | 
 | 527 |                             } | 
 | 528 |                             if (property.first == "LDAPServerURI") | 
 | 529 |                             { | 
 | 530 |                                 confData.uri = *strValue; | 
 | 531 |                             } | 
 | 532 |                             else if (property.first == "LDAPBindDN") | 
 | 533 |                             { | 
 | 534 |                                 confData.bindDN = *strValue; | 
 | 535 |                             } | 
 | 536 |                             else if (property.first == "LDAPBaseDN") | 
 | 537 |                             { | 
 | 538 |                                 confData.baseDN = *strValue; | 
 | 539 |                             } | 
 | 540 |                             else if (property.first == "LDAPSearchScope") | 
 | 541 |                             { | 
 | 542 |                                 confData.searchScope = *strValue; | 
 | 543 |                             } | 
 | 544 |                             else if (property.first == "GroupNameAttribute") | 
 | 545 |                             { | 
 | 546 |                                 confData.groupAttribute = *strValue; | 
 | 547 |                             } | 
 | 548 |                             else if (property.first == "UserNameAttribute") | 
 | 549 |                             { | 
 | 550 |                                 confData.userNameAttribute = *strValue; | 
 | 551 |                             } | 
 | 552 |                             else if (property.first == "LDAPType") | 
 | 553 |                             { | 
 | 554 |                                 confData.serverType = *strValue; | 
 | 555 |                             } | 
 | 556 |                         } | 
 | 557 |                     } | 
 | 558 |                     else if (interface.first == | 
 | 559 |                              "xyz.openbmc_project.User.PrivilegeMapperEntry") | 
 | 560 |                     { | 
 | 561 |                         LDAPRoleMapData roleMapData{}; | 
 | 562 |                         for (const auto& property : interface.second) | 
 | 563 |                         { | 
 | 564 |                             const std::string* strValue = | 
 | 565 |                                 std::get_if<std::string>(&property.second); | 
 | 566 |  | 
 | 567 |                             if (strValue == nullptr) | 
 | 568 |                             { | 
 | 569 |                                 continue; | 
 | 570 |                             } | 
 | 571 |  | 
 | 572 |                             if (property.first == "GroupName") | 
 | 573 |                             { | 
 | 574 |                                 roleMapData.groupName = *strValue; | 
 | 575 |                             } | 
 | 576 |                             else if (property.first == "Privilege") | 
 | 577 |                             { | 
 | 578 |                                 roleMapData.privilege = *strValue; | 
 | 579 |                             } | 
 | 580 |                         } | 
 | 581 |  | 
 | 582 |                         confData.groupRoleList.emplace_back(object.first.str, | 
 | 583 |                                                             roleMapData); | 
 | 584 |                     } | 
 | 585 |                 } | 
 | 586 |             } | 
 | 587 |             callback(true, confData, ldapType); | 
 | 588 |             }, | 
 | 589 |             service, ldapRootObject, dbusObjManagerIntf, "GetManagedObjects"); | 
| Nagaraju Goruganti | 54fc587 | 2019-01-30 05:11:00 -0600 | [diff] [blame] | 590 |         }, | 
 | 591 |         mapperBusName, mapperObjectPath, mapperIntf, "GetObject", | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 592 |         ldapConfigObjectName, interfaces); | 
| Ratan Gupta | 6973a58 | 2018-12-13 18:25:44 +0530 | [diff] [blame] | 593 | } | 
 | 594 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 595 | /** | 
 | 596 |  * @brief parses the authentication section under the LDAP | 
 | 597 |  * @param input JSON data | 
 | 598 |  * @param asyncResp pointer to the JSON response | 
 | 599 |  * @param userName  userName to be filled from the given JSON. | 
 | 600 |  * @param password  password to be filled from the given JSON. | 
 | 601 |  */ | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 602 | inline void parseLDAPAuthenticationJson( | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 603 |     nlohmann::json input, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 604 |     std::optional<std::string>& username, std::optional<std::string>& password) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 605 | { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 606 |     std::optional<std::string> authType; | 
 | 607 |  | 
 | 608 |     if (!json_util::readJson(input, asyncResp->res, "AuthenticationType", | 
 | 609 |                              authType, "Username", username, "Password", | 
 | 610 |                              password)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 611 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 612 |         return; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 613 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 614 |     if (!authType) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 615 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 616 |         return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 617 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 618 |     if (*authType != "UsernameAndPassword") | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 619 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 620 |         messages::propertyValueNotInList(asyncResp->res, *authType, | 
 | 621 |                                          "AuthenticationType"); | 
 | 622 |         return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 623 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 624 | } | 
 | 625 | /** | 
 | 626 |  * @brief parses the LDAPService section under the LDAP | 
 | 627 |  * @param input JSON data | 
 | 628 |  * @param asyncResp pointer to the JSON response | 
 | 629 |  * @param baseDNList baseDN to be filled from the given JSON. | 
 | 630 |  * @param userNameAttribute  userName to be filled from the given JSON. | 
 | 631 |  * @param groupaAttribute  password to be filled from the given JSON. | 
 | 632 |  */ | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 633 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 634 | inline void | 
 | 635 |     parseLDAPServiceJson(nlohmann::json input, | 
 | 636 |                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 637 |                          std::optional<std::vector<std::string>>& baseDNList, | 
 | 638 |                          std::optional<std::string>& userNameAttribute, | 
 | 639 |                          std::optional<std::string>& groupsAttribute) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 640 | { | 
 | 641 |     std::optional<nlohmann::json> searchSettings; | 
 | 642 |  | 
 | 643 |     if (!json_util::readJson(input, asyncResp->res, "SearchSettings", | 
 | 644 |                              searchSettings)) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 645 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 646 |         return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 647 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 648 |     if (!searchSettings) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 649 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 650 |         return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 651 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 652 |     if (!json_util::readJson(*searchSettings, asyncResp->res, | 
 | 653 |                              "BaseDistinguishedNames", baseDNList, | 
 | 654 |                              "UsernameAttribute", userNameAttribute, | 
 | 655 |                              "GroupsAttribute", groupsAttribute)) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 656 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 657 |         return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 658 |     } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 659 | } | 
 | 660 | /** | 
 | 661 |  * @brief updates the LDAP server address and updates the | 
 | 662 |           json response with the new value. | 
 | 663 |  * @param serviceAddressList address to be updated. | 
 | 664 |  * @param asyncResp pointer to the JSON response | 
 | 665 |  * @param ldapServerElementName Type of LDAP | 
 | 666 |  server(openLDAP/ActiveDirectory) | 
 | 667 |  */ | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 668 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 669 | inline void handleServiceAddressPatch( | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 670 |     const std::vector<std::string>& serviceAddressList, | 
 | 671 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 672 |     const std::string& ldapServerElementName, | 
 | 673 |     const std::string& ldapConfigObject) | 
 | 674 | { | 
 | 675 |     crow::connections::systemBus->async_method_call( | 
 | 676 |         [asyncResp, ldapServerElementName, | 
 | 677 |          serviceAddressList](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 678 |         if (ec) | 
 | 679 |         { | 
 | 680 |             BMCWEB_LOG_DEBUG | 
 | 681 |                 << "Error Occurred in updating the service address"; | 
 | 682 |             messages::internalError(asyncResp->res); | 
 | 683 |             return; | 
 | 684 |         } | 
 | 685 |         std::vector<std::string> modifiedserviceAddressList = { | 
 | 686 |             serviceAddressList.front()}; | 
 | 687 |         asyncResp->res.jsonValue[ldapServerElementName]["ServiceAddresses"] = | 
 | 688 |             modifiedserviceAddressList; | 
 | 689 |         if ((serviceAddressList).size() > 1) | 
 | 690 |         { | 
 | 691 |             messages::propertyValueModified(asyncResp->res, "ServiceAddresses", | 
 | 692 |                                             serviceAddressList.front()); | 
 | 693 |         } | 
 | 694 |         BMCWEB_LOG_DEBUG << "Updated the service address"; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 695 |         }, | 
 | 696 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
 | 697 |         ldapConfigInterface, "LDAPServerURI", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 698 |         dbus::utility::DbusVariantType(serviceAddressList.front())); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 699 | } | 
 | 700 | /** | 
 | 701 |  * @brief updates the LDAP Bind DN and updates the | 
 | 702 |           json response with the new value. | 
 | 703 |  * @param username name of the user which needs to be updated. | 
 | 704 |  * @param asyncResp pointer to the JSON response | 
 | 705 |  * @param ldapServerElementName Type of LDAP | 
 | 706 |  server(openLDAP/ActiveDirectory) | 
 | 707 |  */ | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 708 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 709 | inline void | 
 | 710 |     handleUserNamePatch(const std::string& username, | 
 | 711 |                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 712 |                         const std::string& ldapServerElementName, | 
 | 713 |                         const std::string& ldapConfigObject) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 714 | { | 
 | 715 |     crow::connections::systemBus->async_method_call( | 
 | 716 |         [asyncResp, username, | 
 | 717 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 718 |         if (ec) | 
 | 719 |         { | 
 | 720 |             BMCWEB_LOG_DEBUG << "Error occurred in updating the username"; | 
 | 721 |             messages::internalError(asyncResp->res); | 
 | 722 |             return; | 
 | 723 |         } | 
 | 724 |         asyncResp->res | 
 | 725 |             .jsonValue[ldapServerElementName]["Authentication"]["Username"] = | 
 | 726 |             username; | 
 | 727 |         BMCWEB_LOG_DEBUG << "Updated the username"; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 728 |         }, | 
 | 729 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 730 |         ldapConfigInterface, "LDAPBindDN", | 
 | 731 |         dbus::utility::DbusVariantType(username)); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 732 | } | 
 | 733 |  | 
 | 734 | /** | 
 | 735 |  * @brief updates the LDAP password | 
 | 736 |  * @param password : ldap password which needs to be updated. | 
 | 737 |  * @param asyncResp pointer to the JSON response | 
 | 738 |  * @param ldapServerElementName Type of LDAP | 
 | 739 |  *        server(openLDAP/ActiveDirectory) | 
 | 740 |  */ | 
 | 741 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 742 | inline void | 
 | 743 |     handlePasswordPatch(const std::string& password, | 
 | 744 |                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 745 |                         const std::string& ldapServerElementName, | 
 | 746 |                         const std::string& ldapConfigObject) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 747 | { | 
 | 748 |     crow::connections::systemBus->async_method_call( | 
 | 749 |         [asyncResp, password, | 
 | 750 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 751 |         if (ec) | 
 | 752 |         { | 
 | 753 |             BMCWEB_LOG_DEBUG << "Error occurred in updating the password"; | 
 | 754 |             messages::internalError(asyncResp->res); | 
 | 755 |             return; | 
 | 756 |         } | 
 | 757 |         asyncResp->res | 
 | 758 |             .jsonValue[ldapServerElementName]["Authentication"]["Password"] = | 
 | 759 |             ""; | 
 | 760 |         BMCWEB_LOG_DEBUG << "Updated the password"; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 761 |         }, | 
 | 762 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
 | 763 |         ldapConfigInterface, "LDAPBindDNPassword", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 764 |         dbus::utility::DbusVariantType(password)); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 765 | } | 
 | 766 |  | 
 | 767 | /** | 
 | 768 |  * @brief updates the LDAP BaseDN and updates the | 
 | 769 |           json response with the new value. | 
 | 770 |  * @param baseDNList baseDN list which needs to be updated. | 
 | 771 |  * @param asyncResp pointer to the JSON response | 
 | 772 |  * @param ldapServerElementName Type of LDAP | 
 | 773 |  server(openLDAP/ActiveDirectory) | 
 | 774 |  */ | 
 | 775 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 776 | inline void | 
 | 777 |     handleBaseDNPatch(const std::vector<std::string>& baseDNList, | 
 | 778 |                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 779 |                       const std::string& ldapServerElementName, | 
 | 780 |                       const std::string& ldapConfigObject) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 781 | { | 
 | 782 |     crow::connections::systemBus->async_method_call( | 
 | 783 |         [asyncResp, baseDNList, | 
 | 784 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 785 |         if (ec) | 
 | 786 |         { | 
 | 787 |             BMCWEB_LOG_DEBUG << "Error Occurred in Updating the base DN"; | 
 | 788 |             messages::internalError(asyncResp->res); | 
 | 789 |             return; | 
 | 790 |         } | 
 | 791 |         auto& serverTypeJson = asyncResp->res.jsonValue[ldapServerElementName]; | 
 | 792 |         auto& searchSettingsJson = | 
 | 793 |             serverTypeJson["LDAPService"]["SearchSettings"]; | 
 | 794 |         std::vector<std::string> modifiedBaseDNList = {baseDNList.front()}; | 
 | 795 |         searchSettingsJson["BaseDistinguishedNames"] = modifiedBaseDNList; | 
 | 796 |         if (baseDNList.size() > 1) | 
 | 797 |         { | 
 | 798 |             messages::propertyValueModified( | 
 | 799 |                 asyncResp->res, "BaseDistinguishedNames", baseDNList.front()); | 
 | 800 |         } | 
 | 801 |         BMCWEB_LOG_DEBUG << "Updated the base DN"; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 802 |         }, | 
 | 803 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
 | 804 |         ldapConfigInterface, "LDAPBaseDN", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 805 |         dbus::utility::DbusVariantType(baseDNList.front())); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 806 | } | 
 | 807 | /** | 
 | 808 |  * @brief updates the LDAP user name attribute and updates the | 
 | 809 |           json response with the new value. | 
 | 810 |  * @param userNameAttribute attribute to be updated. | 
 | 811 |  * @param asyncResp pointer to the JSON response | 
 | 812 |  * @param ldapServerElementName Type of LDAP | 
 | 813 |  server(openLDAP/ActiveDirectory) | 
 | 814 |  */ | 
 | 815 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 816 | inline void | 
 | 817 |     handleUserNameAttrPatch(const std::string& userNameAttribute, | 
 | 818 |                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 819 |                             const std::string& ldapServerElementName, | 
 | 820 |                             const std::string& ldapConfigObject) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 821 | { | 
 | 822 |     crow::connections::systemBus->async_method_call( | 
 | 823 |         [asyncResp, userNameAttribute, | 
 | 824 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 825 |         if (ec) | 
 | 826 |         { | 
 | 827 |             BMCWEB_LOG_DEBUG << "Error Occurred in Updating the " | 
 | 828 |                                 "username attribute"; | 
 | 829 |             messages::internalError(asyncResp->res); | 
 | 830 |             return; | 
 | 831 |         } | 
 | 832 |         auto& serverTypeJson = asyncResp->res.jsonValue[ldapServerElementName]; | 
 | 833 |         auto& searchSettingsJson = | 
 | 834 |             serverTypeJson["LDAPService"]["SearchSettings"]; | 
 | 835 |         searchSettingsJson["UsernameAttribute"] = userNameAttribute; | 
 | 836 |         BMCWEB_LOG_DEBUG << "Updated the user name attr."; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 837 |         }, | 
 | 838 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
 | 839 |         ldapConfigInterface, "UserNameAttribute", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 840 |         dbus::utility::DbusVariantType(userNameAttribute)); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 841 | } | 
 | 842 | /** | 
 | 843 |  * @brief updates the LDAP group attribute and updates the | 
 | 844 |           json response with the new value. | 
 | 845 |  * @param groupsAttribute attribute to be updated. | 
 | 846 |  * @param asyncResp pointer to the JSON response | 
 | 847 |  * @param ldapServerElementName Type of LDAP | 
 | 848 |  server(openLDAP/ActiveDirectory) | 
 | 849 |  */ | 
 | 850 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 851 | inline void handleGroupNameAttrPatch( | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 852 |     const std::string& groupsAttribute, | 
 | 853 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 854 |     const std::string& ldapServerElementName, | 
 | 855 |     const std::string& ldapConfigObject) | 
 | 856 | { | 
 | 857 |     crow::connections::systemBus->async_method_call( | 
 | 858 |         [asyncResp, groupsAttribute, | 
 | 859 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 860 |         if (ec) | 
 | 861 |         { | 
 | 862 |             BMCWEB_LOG_DEBUG << "Error Occurred in Updating the " | 
 | 863 |                                 "groupname attribute"; | 
 | 864 |             messages::internalError(asyncResp->res); | 
 | 865 |             return; | 
 | 866 |         } | 
 | 867 |         auto& serverTypeJson = asyncResp->res.jsonValue[ldapServerElementName]; | 
 | 868 |         auto& searchSettingsJson = | 
 | 869 |             serverTypeJson["LDAPService"]["SearchSettings"]; | 
 | 870 |         searchSettingsJson["GroupsAttribute"] = groupsAttribute; | 
 | 871 |         BMCWEB_LOG_DEBUG << "Updated the groupname attr"; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 872 |         }, | 
 | 873 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
 | 874 |         ldapConfigInterface, "GroupNameAttribute", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 875 |         dbus::utility::DbusVariantType(groupsAttribute)); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 876 | } | 
 | 877 | /** | 
 | 878 |  * @brief updates the LDAP service enable and updates the | 
 | 879 |           json response with the new value. | 
 | 880 |  * @param input JSON data. | 
 | 881 |  * @param asyncResp pointer to the JSON response | 
 | 882 |  * @param ldapServerElementName Type of LDAP | 
 | 883 |  server(openLDAP/ActiveDirectory) | 
 | 884 |  */ | 
 | 885 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 886 | inline void handleServiceEnablePatch( | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 887 |     bool serviceEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 888 |     const std::string& ldapServerElementName, | 
 | 889 |     const std::string& ldapConfigObject) | 
 | 890 | { | 
 | 891 |     crow::connections::systemBus->async_method_call( | 
 | 892 |         [asyncResp, serviceEnabled, | 
 | 893 |          ldapServerElementName](const boost::system::error_code ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 894 |         if (ec) | 
 | 895 |         { | 
 | 896 |             BMCWEB_LOG_DEBUG << "Error Occurred in Updating the service enable"; | 
 | 897 |             messages::internalError(asyncResp->res); | 
 | 898 |             return; | 
 | 899 |         } | 
 | 900 |         asyncResp->res.jsonValue[ldapServerElementName]["ServiceEnabled"] = | 
 | 901 |             serviceEnabled; | 
 | 902 |         BMCWEB_LOG_DEBUG << "Updated Service enable = " << serviceEnabled; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 903 |         }, | 
 | 904 |         ldapDbusService, ldapConfigObject, propertyInterface, "Set", | 
| Ed Tanous | 168e20c | 2021-12-13 14:39:53 -0800 | [diff] [blame] | 905 |         ldapEnableInterface, "Enabled", | 
 | 906 |         dbus::utility::DbusVariantType(serviceEnabled)); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 907 | } | 
 | 908 |  | 
| Ed Tanous | 4f48d5f | 2021-06-21 08:27:45 -0700 | [diff] [blame] | 909 | inline void | 
 | 910 |     handleAuthMethodsPatch(nlohmann::json& input, | 
 | 911 |                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 912 | { | 
 | 913 |     std::optional<bool> basicAuth; | 
 | 914 |     std::optional<bool> cookie; | 
 | 915 |     std::optional<bool> sessionToken; | 
 | 916 |     std::optional<bool> xToken; | 
 | 917 |     std::optional<bool> tls; | 
 | 918 |  | 
 | 919 |     if (!json_util::readJson(input, asyncResp->res, "BasicAuth", basicAuth, | 
 | 920 |                              "Cookie", cookie, "SessionToken", sessionToken, | 
 | 921 |                              "XToken", xToken, "TLS", tls)) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 922 |     { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 923 |         BMCWEB_LOG_ERROR << "Cannot read values from AuthMethod tag"; | 
 | 924 |         return; | 
 | 925 |     } | 
 | 926 |  | 
 | 927 |     // Make a copy of methods configuration | 
 | 928 |     persistent_data::AuthConfigMethods authMethodsConfig = | 
 | 929 |         persistent_data::SessionStore::getInstance().getAuthMethodsConfig(); | 
 | 930 |  | 
 | 931 |     if (basicAuth) | 
 | 932 |     { | 
 | 933 | #ifndef BMCWEB_ENABLE_BASIC_AUTHENTICATION | 
 | 934 |         messages::actionNotSupported( | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 935 |             asyncResp->res, | 
 | 936 |             "Setting BasicAuth when basic-auth feature is disabled"); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 937 |         return; | 
 | 938 | #endif | 
 | 939 |         authMethodsConfig.basic = *basicAuth; | 
 | 940 |     } | 
 | 941 |  | 
 | 942 |     if (cookie) | 
 | 943 |     { | 
 | 944 | #ifndef BMCWEB_ENABLE_COOKIE_AUTHENTICATION | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 945 |         messages::actionNotSupported( | 
 | 946 |             asyncResp->res, | 
 | 947 |             "Setting Cookie when cookie-auth feature is disabled"); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 948 |         return; | 
 | 949 | #endif | 
 | 950 |         authMethodsConfig.cookie = *cookie; | 
 | 951 |     } | 
 | 952 |  | 
 | 953 |     if (sessionToken) | 
 | 954 |     { | 
 | 955 | #ifndef BMCWEB_ENABLE_SESSION_AUTHENTICATION | 
 | 956 |         messages::actionNotSupported( | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 957 |             asyncResp->res, | 
 | 958 |             "Setting SessionToken when session-auth feature is disabled"); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 959 |         return; | 
 | 960 | #endif | 
 | 961 |         authMethodsConfig.sessionToken = *sessionToken; | 
 | 962 |     } | 
 | 963 |  | 
 | 964 |     if (xToken) | 
 | 965 |     { | 
 | 966 | #ifndef BMCWEB_ENABLE_XTOKEN_AUTHENTICATION | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 967 |         messages::actionNotSupported( | 
 | 968 |             asyncResp->res, | 
 | 969 |             "Setting XToken when xtoken-auth feature is disabled"); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 970 |         return; | 
 | 971 | #endif | 
 | 972 |         authMethodsConfig.xtoken = *xToken; | 
 | 973 |     } | 
 | 974 |  | 
 | 975 |     if (tls) | 
 | 976 |     { | 
 | 977 | #ifndef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 978 |         messages::actionNotSupported( | 
 | 979 |             asyncResp->res, | 
 | 980 |             "Setting TLS when mutual-tls-auth feature is disabled"); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 981 |         return; | 
 | 982 | #endif | 
 | 983 |         authMethodsConfig.tls = *tls; | 
 | 984 |     } | 
 | 985 |  | 
 | 986 |     if (!authMethodsConfig.basic && !authMethodsConfig.cookie && | 
 | 987 |         !authMethodsConfig.sessionToken && !authMethodsConfig.xtoken && | 
 | 988 |         !authMethodsConfig.tls) | 
 | 989 |     { | 
 | 990 |         // Do not allow user to disable everything | 
 | 991 |         messages::actionNotSupported(asyncResp->res, | 
 | 992 |                                      "of disabling all available methods"); | 
 | 993 |         return; | 
 | 994 |     } | 
 | 995 |  | 
 | 996 |     persistent_data::SessionStore::getInstance().updateAuthMethodsConfig( | 
 | 997 |         authMethodsConfig); | 
 | 998 |     // Save configuration immediately | 
 | 999 |     persistent_data::getConfig().writeData(); | 
 | 1000 |  | 
 | 1001 |     messages::success(asyncResp->res); | 
 | 1002 | } | 
 | 1003 |  | 
 | 1004 | /** | 
 | 1005 |  * @brief Get the required values from the given JSON, validates the | 
 | 1006 |  *        value and create the LDAP config object. | 
 | 1007 |  * @param input JSON data | 
 | 1008 |  * @param asyncResp pointer to the JSON response | 
 | 1009 |  * @param serverType Type of LDAP server(openLDAP/ActiveDirectory) | 
 | 1010 |  */ | 
 | 1011 |  | 
 | 1012 | inline void handleLDAPPatch(nlohmann::json& input, | 
 | 1013 |                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1014 |                             const std::string& serverType) | 
 | 1015 | { | 
 | 1016 |     std::string dbusObjectPath; | 
 | 1017 |     if (serverType == "ActiveDirectory") | 
 | 1018 |     { | 
 | 1019 |         dbusObjectPath = adConfigObject; | 
 | 1020 |     } | 
 | 1021 |     else if (serverType == "LDAP") | 
 | 1022 |     { | 
 | 1023 |         dbusObjectPath = ldapConfigObjectName; | 
 | 1024 |     } | 
 | 1025 |     else | 
 | 1026 |     { | 
 | 1027 |         return; | 
 | 1028 |     } | 
 | 1029 |  | 
 | 1030 |     std::optional<nlohmann::json> authentication; | 
 | 1031 |     std::optional<nlohmann::json> ldapService; | 
 | 1032 |     std::optional<std::vector<std::string>> serviceAddressList; | 
 | 1033 |     std::optional<bool> serviceEnabled; | 
 | 1034 |     std::optional<std::vector<std::string>> baseDNList; | 
 | 1035 |     std::optional<std::string> userNameAttribute; | 
 | 1036 |     std::optional<std::string> groupsAttribute; | 
 | 1037 |     std::optional<std::string> userName; | 
 | 1038 |     std::optional<std::string> password; | 
 | 1039 |     std::optional<std::vector<nlohmann::json>> remoteRoleMapData; | 
 | 1040 |  | 
 | 1041 |     if (!json_util::readJson(input, asyncResp->res, "Authentication", | 
 | 1042 |                              authentication, "LDAPService", ldapService, | 
 | 1043 |                              "ServiceAddresses", serviceAddressList, | 
 | 1044 |                              "ServiceEnabled", serviceEnabled, | 
 | 1045 |                              "RemoteRoleMapping", remoteRoleMapData)) | 
 | 1046 |     { | 
 | 1047 |         return; | 
 | 1048 |     } | 
 | 1049 |  | 
 | 1050 |     if (authentication) | 
 | 1051 |     { | 
 | 1052 |         parseLDAPAuthenticationJson(*authentication, asyncResp, userName, | 
 | 1053 |                                     password); | 
 | 1054 |     } | 
 | 1055 |     if (ldapService) | 
 | 1056 |     { | 
 | 1057 |         parseLDAPServiceJson(*ldapService, asyncResp, baseDNList, | 
 | 1058 |                              userNameAttribute, groupsAttribute); | 
 | 1059 |     } | 
 | 1060 |     if (serviceAddressList) | 
 | 1061 |     { | 
| Ed Tanous | 26f6976 | 2022-01-25 09:49:11 -0800 | [diff] [blame] | 1062 |         if (serviceAddressList->empty()) | 
| Ratan Gupta | eb2bbe5 | 2019-04-22 14:27:01 +0530 | [diff] [blame] | 1063 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1064 |             messages::propertyValueNotInList(asyncResp->res, "[]", | 
 | 1065 |                                              "ServiceAddress"); | 
| Ed Tanous | cb13a39 | 2020-07-25 19:02:03 +0000 | [diff] [blame] | 1066 |             return; | 
 | 1067 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1068 |     } | 
 | 1069 |     if (baseDNList) | 
 | 1070 |     { | 
| Ed Tanous | 26f6976 | 2022-01-25 09:49:11 -0800 | [diff] [blame] | 1071 |         if (baseDNList->empty()) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1072 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1073 |             messages::propertyValueNotInList(asyncResp->res, "[]", | 
 | 1074 |                                              "BaseDistinguishedNames"); | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1075 |             return; | 
 | 1076 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1077 |     } | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1078 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1079 |     // nothing to update, then return | 
 | 1080 |     if (!userName && !password && !serviceAddressList && !baseDNList && | 
 | 1081 |         !userNameAttribute && !groupsAttribute && !serviceEnabled && | 
 | 1082 |         !remoteRoleMapData) | 
 | 1083 |     { | 
 | 1084 |         return; | 
 | 1085 |     } | 
 | 1086 |  | 
 | 1087 |     // Get the existing resource first then keep modifying | 
 | 1088 |     // whenever any property gets updated. | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1089 |     getLDAPConfigData( | 
 | 1090 |         serverType, | 
 | 1091 |         [asyncResp, userName, password, baseDNList, userNameAttribute, | 
 | 1092 |          groupsAttribute, serviceAddressList, serviceEnabled, dbusObjectPath, | 
 | 1093 |          remoteRoleMapData](bool success, const LDAPConfigData& confData, | 
 | 1094 |                             const std::string& serverT) { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1095 |         if (!success) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1096 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1097 |             messages::internalError(asyncResp->res); | 
 | 1098 |             return; | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1099 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1100 |         parseLDAPConfigData(asyncResp->res.jsonValue, confData, serverT); | 
 | 1101 |         if (confData.serviceEnabled) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1102 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1103 |             // Disable the service first and update the rest of | 
 | 1104 |             // the properties. | 
 | 1105 |             handleServiceEnablePatch(false, asyncResp, serverT, dbusObjectPath); | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1106 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1107 |  | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1108 |         if (serviceAddressList) | 
 | 1109 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1110 |             handleServiceAddressPatch(*serviceAddressList, asyncResp, serverT, | 
 | 1111 |                                       dbusObjectPath); | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1112 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1113 |         if (userName) | 
 | 1114 |         { | 
 | 1115 |             handleUserNamePatch(*userName, asyncResp, serverT, dbusObjectPath); | 
 | 1116 |         } | 
 | 1117 |         if (password) | 
 | 1118 |         { | 
 | 1119 |             handlePasswordPatch(*password, asyncResp, serverT, dbusObjectPath); | 
 | 1120 |         } | 
 | 1121 |  | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1122 |         if (baseDNList) | 
 | 1123 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1124 |             handleBaseDNPatch(*baseDNList, asyncResp, serverT, dbusObjectPath); | 
 | 1125 |         } | 
 | 1126 |         if (userNameAttribute) | 
 | 1127 |         { | 
 | 1128 |             handleUserNameAttrPatch(*userNameAttribute, asyncResp, serverT, | 
 | 1129 |                                     dbusObjectPath); | 
 | 1130 |         } | 
 | 1131 |         if (groupsAttribute) | 
 | 1132 |         { | 
 | 1133 |             handleGroupNameAttrPatch(*groupsAttribute, asyncResp, serverT, | 
 | 1134 |                                      dbusObjectPath); | 
 | 1135 |         } | 
 | 1136 |         if (serviceEnabled) | 
 | 1137 |         { | 
 | 1138 |             // if user has given the value as true then enable | 
 | 1139 |             // the service. if user has given false then no-op | 
 | 1140 |             // as service is already stopped. | 
 | 1141 |             if (*serviceEnabled) | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1142 |             { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1143 |                 handleServiceEnablePatch(*serviceEnabled, asyncResp, serverT, | 
 | 1144 |                                          dbusObjectPath); | 
| Ratan Gupta | 8a07d28 | 2019-03-16 08:33:47 +0530 | [diff] [blame] | 1145 |             } | 
 | 1146 |         } | 
| jayaprakash Mutyala | 9620060 | 2020-04-08 11:09:10 +0000 | [diff] [blame] | 1147 |         else | 
 | 1148 |         { | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1149 |             // if user has not given the service enabled value | 
 | 1150 |             // then revert it to the same state as it was | 
 | 1151 |             // before. | 
 | 1152 |             handleServiceEnablePatch(confData.serviceEnabled, asyncResp, | 
 | 1153 |                                      serverT, dbusObjectPath); | 
| jayaprakash Mutyala | 9620060 | 2020-04-08 11:09:10 +0000 | [diff] [blame] | 1154 |         } | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1155 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1156 |         if (remoteRoleMapData) | 
 | 1157 |         { | 
 | 1158 |             handleRoleMapPatch(asyncResp, confData.groupRoleList, serverT, | 
 | 1159 |                                *remoteRoleMapData); | 
 | 1160 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1161 |         }); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1162 | } | 
 | 1163 |  | 
 | 1164 | inline void updateUserProperties(std::shared_ptr<bmcweb::AsyncResp> asyncResp, | 
 | 1165 |                                  const std::string& username, | 
 | 1166 |                                  std::optional<std::string> password, | 
 | 1167 |                                  std::optional<bool> enabled, | 
 | 1168 |                                  std::optional<std::string> roleId, | 
 | 1169 |                                  std::optional<bool> locked) | 
 | 1170 | { | 
| P Dheeraj Srujan Kumar | b477fd4 | 2021-12-16 07:17:51 +0530 | [diff] [blame] | 1171 |     sdbusplus::message::object_path tempObjPath(rootUserDbusPath); | 
 | 1172 |     tempObjPath /= username; | 
 | 1173 |     std::string dbusObjectPath(tempObjPath); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1174 |  | 
 | 1175 |     dbus::utility::checkDbusPathExists( | 
 | 1176 |         dbusObjectPath, | 
| Ed Tanous | 1106333 | 2021-09-24 11:55:44 -0700 | [diff] [blame] | 1177 |         [dbusObjectPath, username, password(std::move(password)), | 
 | 1178 |          roleId(std::move(roleId)), enabled, locked, | 
 | 1179 |          asyncResp{std::move(asyncResp)}](int rc) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1180 |         if (rc <= 0) | 
 | 1181 |         { | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1182 |             messages::resourceNotFound(asyncResp->res, "ManagerAccount", | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1183 |                                        username); | 
 | 1184 |             return; | 
 | 1185 |         } | 
 | 1186 |  | 
 | 1187 |         if (password) | 
 | 1188 |         { | 
 | 1189 |             int retval = pamUpdatePassword(username, *password); | 
 | 1190 |  | 
 | 1191 |             if (retval == PAM_USER_UNKNOWN) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1192 |             { | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1193 |                 messages::resourceNotFound(asyncResp->res, "ManagerAccount", | 
 | 1194 |                                            username); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1195 |             } | 
 | 1196 |             else if (retval == PAM_AUTHTOK_ERR) | 
 | 1197 |             { | 
 | 1198 |                 // If password is invalid | 
 | 1199 |                 messages::propertyValueFormatError(asyncResp->res, *password, | 
 | 1200 |                                                    "Password"); | 
 | 1201 |                 BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; | 
 | 1202 |             } | 
 | 1203 |             else if (retval != PAM_SUCCESS) | 
 | 1204 |             { | 
 | 1205 |                 messages::internalError(asyncResp->res); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1206 |                 return; | 
 | 1207 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1208 |             else | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1209 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1210 |                 messages::success(asyncResp->res); | 
 | 1211 |             } | 
 | 1212 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1213 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1214 |         if (enabled) | 
 | 1215 |         { | 
 | 1216 |             crow::connections::systemBus->async_method_call( | 
 | 1217 |                 [asyncResp](const boost::system::error_code ec) { | 
 | 1218 |                 if (ec) | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1219 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1220 |                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; | 
| Ayushi Smriti | 599c71d | 2019-08-23 17:43:18 +0000 | [diff] [blame] | 1221 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1222 |                     return; | 
 | 1223 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1224 |                 messages::success(asyncResp->res); | 
 | 1225 |                 return; | 
 | 1226 |                 }, | 
 | 1227 |                 "xyz.openbmc_project.User.Manager", dbusObjectPath, | 
 | 1228 |                 "org.freedesktop.DBus.Properties", "Set", | 
 | 1229 |                 "xyz.openbmc_project.User.Attributes", "UserEnabled", | 
 | 1230 |                 dbus::utility::DbusVariantType{*enabled}); | 
 | 1231 |         } | 
 | 1232 |  | 
 | 1233 |         if (roleId) | 
 | 1234 |         { | 
 | 1235 |             std::string priv = getPrivilegeFromRoleId(*roleId); | 
 | 1236 |             if (priv.empty()) | 
 | 1237 |             { | 
 | 1238 |                 messages::propertyValueNotInList(asyncResp->res, *roleId, | 
 | 1239 |                                                  "RoleId"); | 
 | 1240 |                 return; | 
 | 1241 |             } | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1242 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1243 |             crow::connections::systemBus->async_method_call( | 
 | 1244 |                 [asyncResp](const boost::system::error_code ec) { | 
 | 1245 |                 if (ec) | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1246 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1247 |                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; | 
 | 1248 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1249 |                     return; | 
 | 1250 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1251 |                 messages::success(asyncResp->res); | 
 | 1252 |                 }, | 
 | 1253 |                 "xyz.openbmc_project.User.Manager", dbusObjectPath, | 
 | 1254 |                 "org.freedesktop.DBus.Properties", "Set", | 
 | 1255 |                 "xyz.openbmc_project.User.Attributes", "UserPrivilege", | 
 | 1256 |                 dbus::utility::DbusVariantType{priv}); | 
 | 1257 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1258 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1259 |         if (locked) | 
 | 1260 |         { | 
 | 1261 |             // admin can unlock the account which is locked by | 
 | 1262 |             // successive authentication failures but admin should | 
 | 1263 |             // not be allowed to lock an account. | 
 | 1264 |             if (*locked) | 
 | 1265 |             { | 
 | 1266 |                 messages::propertyValueNotInList(asyncResp->res, "true", | 
 | 1267 |                                                  "Locked"); | 
 | 1268 |                 return; | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1269 |             } | 
 | 1270 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1271 |             crow::connections::systemBus->async_method_call( | 
 | 1272 |                 [asyncResp](const boost::system::error_code ec) { | 
 | 1273 |                 if (ec) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1274 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1275 |                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; | 
 | 1276 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 04ae99e | 2018-09-20 15:54:36 -0700 | [diff] [blame] | 1277 |                     return; | 
 | 1278 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1279 |                 messages::success(asyncResp->res); | 
 | 1280 |                 return; | 
 | 1281 |                 }, | 
 | 1282 |                 "xyz.openbmc_project.User.Manager", dbusObjectPath, | 
 | 1283 |                 "org.freedesktop.DBus.Properties", "Set", | 
 | 1284 |                 "xyz.openbmc_project.User.Attributes", | 
 | 1285 |                 "UserLockedForFailedAttempt", | 
 | 1286 |                 dbus::utility::DbusVariantType{*locked}); | 
 | 1287 |         } | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 1288 |         }); | 
 | 1289 | } | 
| Ed Tanous | b9b2e0b | 2018-09-13 13:47:50 -0700 | [diff] [blame] | 1290 |  | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1291 | inline void handleAccountServiceHead( | 
 | 1292 |     App& app, const crow::Request& req, | 
 | 1293 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1294 | { | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1295 |  | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1296 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1297 |     { | 
 | 1298 |         return; | 
 | 1299 |     } | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1300 |     asyncResp->res.addHeader( | 
 | 1301 |         boost::beast::http::field::link, | 
 | 1302 |         "</redfish/v1/JsonSchemas/AccountService/AccountService.json>; rel=describedby"); | 
 | 1303 | } | 
 | 1304 |  | 
 | 1305 | inline void | 
 | 1306 |     handleAccountServiceGet(App& app, const crow::Request& req, | 
 | 1307 |                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 1308 | { | 
 | 1309 |     handleAccountServiceHead(app, req, asyncResp); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1310 |     const persistent_data::AuthConfigMethods& authMethodsConfig = | 
 | 1311 |         persistent_data::SessionStore::getInstance().getAuthMethodsConfig(); | 
 | 1312 |  | 
 | 1313 |     nlohmann::json& json = asyncResp->res.jsonValue; | 
 | 1314 |     json["@odata.id"] = "/redfish/v1/AccountService"; | 
 | 1315 |     json["@odata.type"] = "#AccountService." | 
 | 1316 |                           "v1_10_0.AccountService"; | 
 | 1317 |     json["Id"] = "AccountService"; | 
 | 1318 |     json["Name"] = "Account Service"; | 
 | 1319 |     json["Description"] = "Account Service"; | 
 | 1320 |     json["ServiceEnabled"] = true; | 
 | 1321 |     json["MaxPasswordLength"] = 20; | 
 | 1322 |     json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts"; | 
 | 1323 |     json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles"; | 
 | 1324 |     json["Oem"]["OpenBMC"]["@odata.type"] = | 
 | 1325 |         "#OemAccountService.v1_0_0.AccountService"; | 
 | 1326 |     json["Oem"]["OpenBMC"]["@odata.id"] = | 
 | 1327 |         "/redfish/v1/AccountService#/Oem/OpenBMC"; | 
 | 1328 |     json["Oem"]["OpenBMC"]["AuthMethods"]["BasicAuth"] = | 
 | 1329 |         authMethodsConfig.basic; | 
 | 1330 |     json["Oem"]["OpenBMC"]["AuthMethods"]["SessionToken"] = | 
 | 1331 |         authMethodsConfig.sessionToken; | 
 | 1332 |     json["Oem"]["OpenBMC"]["AuthMethods"]["XToken"] = authMethodsConfig.xtoken; | 
 | 1333 |     json["Oem"]["OpenBMC"]["AuthMethods"]["Cookie"] = authMethodsConfig.cookie; | 
 | 1334 |     json["Oem"]["OpenBMC"]["AuthMethods"]["TLS"] = authMethodsConfig.tls; | 
 | 1335 |  | 
 | 1336 |     // /redfish/v1/AccountService/LDAP/Certificates is something only | 
 | 1337 |     // ConfigureManager can access then only display when the user has | 
 | 1338 |     // permissions ConfigureManager | 
 | 1339 |     Privileges effectiveUserPrivileges = | 
 | 1340 |         redfish::getUserPrivileges(req.userRole); | 
 | 1341 |  | 
 | 1342 |     if (isOperationAllowedWithPrivileges({{"ConfigureManager"}}, | 
 | 1343 |                                          effectiveUserPrivileges)) | 
 | 1344 |     { | 
 | 1345 |         asyncResp->res.jsonValue["LDAP"]["Certificates"]["@odata.id"] = | 
 | 1346 |             "/redfish/v1/AccountService/LDAP/Certificates"; | 
 | 1347 |     } | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1348 |     sdbusplus::asio::getAllProperties( | 
 | 1349 |         *crow::connections::systemBus, "xyz.openbmc_project.User.Manager", | 
 | 1350 |         "/xyz/openbmc_project/user", "xyz.openbmc_project.User.AccountPolicy", | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1351 |         [asyncResp](const boost::system::error_code ec, | 
 | 1352 |                     const dbus::utility::DBusPropertiesMap& propertiesList) { | 
 | 1353 |         if (ec) | 
 | 1354 |         { | 
 | 1355 |             messages::internalError(asyncResp->res); | 
 | 1356 |             return; | 
 | 1357 |         } | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1358 |  | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1359 |         BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() | 
 | 1360 |                          << "properties for AccountService"; | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1361 |  | 
 | 1362 |         const uint8_t* minPasswordLength = nullptr; | 
 | 1363 |         const uint32_t* accountUnlockTimeout = nullptr; | 
 | 1364 |         const uint16_t* maxLoginAttemptBeforeLockout = nullptr; | 
 | 1365 |  | 
 | 1366 |         const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 1367 |             dbus_utils::UnpackErrorPrinter(), propertiesList, | 
 | 1368 |             "MinPasswordLength", minPasswordLength, "AccountUnlockTimeout", | 
 | 1369 |             accountUnlockTimeout, "MaxLoginAttemptBeforeLockout", | 
 | 1370 |             maxLoginAttemptBeforeLockout); | 
 | 1371 |  | 
 | 1372 |         if (!success) | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1373 |         { | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1374 |             messages::internalError(asyncResp->res); | 
 | 1375 |             return; | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1376 |         } | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1377 |  | 
 | 1378 |         if (minPasswordLength != nullptr) | 
 | 1379 |         { | 
 | 1380 |             asyncResp->res.jsonValue["MinPasswordLength"] = *minPasswordLength; | 
 | 1381 |         } | 
 | 1382 |  | 
 | 1383 |         if (accountUnlockTimeout != nullptr) | 
 | 1384 |         { | 
 | 1385 |             asyncResp->res.jsonValue["AccountLockoutDuration"] = | 
 | 1386 |                 *accountUnlockTimeout; | 
 | 1387 |         } | 
 | 1388 |  | 
 | 1389 |         if (maxLoginAttemptBeforeLockout != nullptr) | 
 | 1390 |         { | 
 | 1391 |             asyncResp->res.jsonValue["AccountLockoutThreshold"] = | 
 | 1392 |                 *maxLoginAttemptBeforeLockout; | 
 | 1393 |         } | 
 | 1394 |         }); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1395 |  | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 1396 |     auto callback = [asyncResp](bool success, const LDAPConfigData& confData, | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1397 |                                 const std::string& ldapType) { | 
 | 1398 |         if (!success) | 
 | 1399 |         { | 
 | 1400 |             return; | 
 | 1401 |         } | 
 | 1402 |         parseLDAPConfigData(asyncResp->res.jsonValue, confData, ldapType); | 
 | 1403 |     }; | 
 | 1404 |  | 
 | 1405 |     getLDAPConfigData("LDAP", callback); | 
 | 1406 |     getLDAPConfigData("ActiveDirectory", callback); | 
 | 1407 | } | 
 | 1408 |  | 
 | 1409 | inline void handleAccountServicePatch( | 
 | 1410 |     App& app, const crow::Request& req, | 
 | 1411 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 1412 | { | 
 | 1413 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1414 |     { | 
 | 1415 |         return; | 
 | 1416 |     } | 
 | 1417 |     std::optional<uint32_t> unlockTimeout; | 
 | 1418 |     std::optional<uint16_t> lockoutThreshold; | 
 | 1419 |     std::optional<uint8_t> minPasswordLength; | 
 | 1420 |     std::optional<uint16_t> maxPasswordLength; | 
 | 1421 |     std::optional<nlohmann::json> ldapObject; | 
 | 1422 |     std::optional<nlohmann::json> activeDirectoryObject; | 
 | 1423 |     std::optional<nlohmann::json> oemObject; | 
 | 1424 |  | 
 | 1425 |     if (!json_util::readJsonPatch( | 
 | 1426 |             req, asyncResp->res, "AccountLockoutDuration", unlockTimeout, | 
 | 1427 |             "AccountLockoutThreshold", lockoutThreshold, "MaxPasswordLength", | 
 | 1428 |             maxPasswordLength, "MinPasswordLength", minPasswordLength, "LDAP", | 
 | 1429 |             ldapObject, "ActiveDirectory", activeDirectoryObject, "Oem", | 
 | 1430 |             oemObject)) | 
 | 1431 |     { | 
 | 1432 |         return; | 
 | 1433 |     } | 
 | 1434 |  | 
 | 1435 |     if (minPasswordLength) | 
 | 1436 |     { | 
 | 1437 |         crow::connections::systemBus->async_method_call( | 
 | 1438 |             [asyncResp](const boost::system::error_code ec) { | 
 | 1439 |             if (ec) | 
 | 1440 |             { | 
 | 1441 |                 messages::internalError(asyncResp->res); | 
 | 1442 |                 return; | 
 | 1443 |             } | 
 | 1444 |             messages::success(asyncResp->res); | 
 | 1445 |             }, | 
 | 1446 |             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1447 |             "org.freedesktop.DBus.Properties", "Set", | 
 | 1448 |             "xyz.openbmc_project.User.AccountPolicy", "MinPasswordLength", | 
 | 1449 |             dbus::utility::DbusVariantType(*minPasswordLength)); | 
 | 1450 |     } | 
 | 1451 |  | 
 | 1452 |     if (maxPasswordLength) | 
 | 1453 |     { | 
 | 1454 |         messages::propertyNotWritable(asyncResp->res, "MaxPasswordLength"); | 
 | 1455 |     } | 
 | 1456 |  | 
 | 1457 |     if (ldapObject) | 
 | 1458 |     { | 
 | 1459 |         handleLDAPPatch(*ldapObject, asyncResp, "LDAP"); | 
 | 1460 |     } | 
 | 1461 |  | 
 | 1462 |     if (std::optional<nlohmann::json> oemOpenBMCObject; | 
 | 1463 |         oemObject && json_util::readJson(*oemObject, asyncResp->res, "OpenBMC", | 
 | 1464 |                                          oemOpenBMCObject)) | 
 | 1465 |     { | 
 | 1466 |         if (std::optional<nlohmann::json> authMethodsObject; | 
 | 1467 |             oemOpenBMCObject && | 
 | 1468 |             json_util::readJson(*oemOpenBMCObject, asyncResp->res, | 
 | 1469 |                                 "AuthMethods", authMethodsObject)) | 
 | 1470 |         { | 
 | 1471 |             if (authMethodsObject) | 
 | 1472 |             { | 
 | 1473 |                 handleAuthMethodsPatch(*authMethodsObject, asyncResp); | 
 | 1474 |             } | 
 | 1475 |         } | 
 | 1476 |     } | 
 | 1477 |  | 
 | 1478 |     if (activeDirectoryObject) | 
 | 1479 |     { | 
 | 1480 |         handleLDAPPatch(*activeDirectoryObject, asyncResp, "ActiveDirectory"); | 
 | 1481 |     } | 
 | 1482 |  | 
 | 1483 |     if (unlockTimeout) | 
 | 1484 |     { | 
 | 1485 |         crow::connections::systemBus->async_method_call( | 
 | 1486 |             [asyncResp](const boost::system::error_code ec) { | 
 | 1487 |             if (ec) | 
 | 1488 |             { | 
 | 1489 |                 messages::internalError(asyncResp->res); | 
 | 1490 |                 return; | 
 | 1491 |             } | 
 | 1492 |             messages::success(asyncResp->res); | 
 | 1493 |             }, | 
 | 1494 |             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1495 |             "org.freedesktop.DBus.Properties", "Set", | 
 | 1496 |             "xyz.openbmc_project.User.AccountPolicy", "AccountUnlockTimeout", | 
 | 1497 |             dbus::utility::DbusVariantType(*unlockTimeout)); | 
 | 1498 |     } | 
 | 1499 |     if (lockoutThreshold) | 
 | 1500 |     { | 
 | 1501 |         crow::connections::systemBus->async_method_call( | 
 | 1502 |             [asyncResp](const boost::system::error_code ec) { | 
 | 1503 |             if (ec) | 
 | 1504 |             { | 
 | 1505 |                 messages::internalError(asyncResp->res); | 
 | 1506 |                 return; | 
 | 1507 |             } | 
 | 1508 |             messages::success(asyncResp->res); | 
 | 1509 |             }, | 
 | 1510 |             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1511 |             "org.freedesktop.DBus.Properties", "Set", | 
 | 1512 |             "xyz.openbmc_project.User.AccountPolicy", | 
 | 1513 |             "MaxLoginAttemptBeforeLockout", | 
 | 1514 |             dbus::utility::DbusVariantType(*lockoutThreshold)); | 
 | 1515 |     } | 
 | 1516 | } | 
 | 1517 |  | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1518 | inline void handleAccountCollectionHead( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1519 |     App& app, const crow::Request& req, | 
 | 1520 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 1521 | { | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1522 |  | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1523 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1524 |     { | 
 | 1525 |         return; | 
 | 1526 |     } | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1527 |     asyncResp->res.addHeader( | 
 | 1528 |         boost::beast::http::field::link, | 
 | 1529 |         "</redfish/v1/JsonSchemas/ManagerAccountCollection.json>; rel=describedby"); | 
 | 1530 | } | 
 | 1531 |  | 
 | 1532 | inline void handleAccountCollectionGet( | 
 | 1533 |     App& app, const crow::Request& req, | 
 | 1534 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 1535 | { | 
 | 1536 |     handleAccountCollectionHead(app, req, asyncResp); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1537 |  | 
 | 1538 |     asyncResp->res.jsonValue["@odata.id"] = | 
 | 1539 |         "/redfish/v1/AccountService/Accounts"; | 
 | 1540 |     asyncResp->res.jsonValue["@odata.type"] = "#ManagerAccountCollection." | 
 | 1541 |                                               "ManagerAccountCollection"; | 
 | 1542 |     asyncResp->res.jsonValue["Name"] = "Accounts Collection"; | 
 | 1543 |     asyncResp->res.jsonValue["Description"] = "BMC User Accounts"; | 
 | 1544 |  | 
 | 1545 |     Privileges effectiveUserPrivileges = | 
 | 1546 |         redfish::getUserPrivileges(req.userRole); | 
 | 1547 |  | 
 | 1548 |     std::string thisUser; | 
 | 1549 |     if (req.session) | 
 | 1550 |     { | 
 | 1551 |         thisUser = req.session->username; | 
 | 1552 |     } | 
 | 1553 |     crow::connections::systemBus->async_method_call( | 
 | 1554 |         [asyncResp, thisUser, effectiveUserPrivileges]( | 
 | 1555 |             const boost::system::error_code ec, | 
 | 1556 |             const dbus::utility::ManagedObjectType& users) { | 
 | 1557 |         if (ec) | 
 | 1558 |         { | 
 | 1559 |             messages::internalError(asyncResp->res); | 
 | 1560 |             return; | 
 | 1561 |         } | 
 | 1562 |  | 
 | 1563 |         bool userCanSeeAllAccounts = | 
 | 1564 |             effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"}); | 
 | 1565 |  | 
 | 1566 |         bool userCanSeeSelf = | 
 | 1567 |             effectiveUserPrivileges.isSupersetOf({"ConfigureSelf"}); | 
 | 1568 |  | 
 | 1569 |         nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; | 
 | 1570 |         memberArray = nlohmann::json::array(); | 
 | 1571 |  | 
 | 1572 |         for (const auto& userpath : users) | 
 | 1573 |         { | 
 | 1574 |             std::string user = userpath.first.filename(); | 
 | 1575 |             if (user.empty()) | 
 | 1576 |             { | 
 | 1577 |                 messages::internalError(asyncResp->res); | 
 | 1578 |                 BMCWEB_LOG_ERROR << "Invalid firmware ID"; | 
 | 1579 |  | 
 | 1580 |                 return; | 
 | 1581 |             } | 
 | 1582 |  | 
 | 1583 |             // As clarified by Redfish here: | 
 | 1584 |             // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration | 
 | 1585 |             // Users without ConfigureUsers, only see their own | 
 | 1586 |             // account. Users with ConfigureUsers, see all | 
 | 1587 |             // accounts. | 
 | 1588 |             if (userCanSeeAllAccounts || (thisUser == user && userCanSeeSelf)) | 
 | 1589 |             { | 
 | 1590 |                 nlohmann::json::object_t member; | 
 | 1591 |                 member["@odata.id"] = | 
 | 1592 |                     "/redfish/v1/AccountService/Accounts/" + user; | 
 | 1593 |                 memberArray.push_back(std::move(member)); | 
 | 1594 |             } | 
 | 1595 |         } | 
 | 1596 |         asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size(); | 
 | 1597 |         }, | 
 | 1598 |         "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1599 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 1600 | } | 
 | 1601 |  | 
 | 1602 | inline void handleAccountCollectionPost( | 
 | 1603 |     App& app, const crow::Request& req, | 
 | 1604 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 1605 | { | 
 | 1606 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1607 |     { | 
 | 1608 |         return; | 
 | 1609 |     } | 
 | 1610 |     std::string username; | 
 | 1611 |     std::string password; | 
 | 1612 |     std::optional<std::string> roleId("User"); | 
 | 1613 |     std::optional<bool> enabled = true; | 
 | 1614 |     if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username, | 
 | 1615 |                                   "Password", password, "RoleId", roleId, | 
 | 1616 |                                   "Enabled", enabled)) | 
 | 1617 |     { | 
 | 1618 |         return; | 
 | 1619 |     } | 
 | 1620 |  | 
 | 1621 |     std::string priv = getPrivilegeFromRoleId(*roleId); | 
 | 1622 |     if (priv.empty()) | 
 | 1623 |     { | 
 | 1624 |         messages::propertyValueNotInList(asyncResp->res, *roleId, "RoleId"); | 
 | 1625 |         return; | 
 | 1626 |     } | 
| Asmitha Karunanithi | 239adf8 | 2022-03-25 02:59:03 -0500 | [diff] [blame] | 1627 |     roleId = priv; | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1628 |  | 
 | 1629 |     // Reading AllGroups property | 
 | 1630 |     sdbusplus::asio::getProperty<std::vector<std::string>>( | 
 | 1631 |         *crow::connections::systemBus, "xyz.openbmc_project.User.Manager", | 
 | 1632 |         "/xyz/openbmc_project/user", "xyz.openbmc_project.User.Manager", | 
 | 1633 |         "AllGroups", | 
 | 1634 |         [asyncResp, username, password{std::move(password)}, roleId, | 
 | 1635 |          enabled](const boost::system::error_code ec, | 
 | 1636 |                   const std::vector<std::string>& allGroupsList) { | 
 | 1637 |         if (ec) | 
 | 1638 |         { | 
 | 1639 |             BMCWEB_LOG_DEBUG << "ERROR with async_method_call"; | 
 | 1640 |             messages::internalError(asyncResp->res); | 
 | 1641 |             return; | 
 | 1642 |         } | 
 | 1643 |  | 
 | 1644 |         if (allGroupsList.empty()) | 
 | 1645 |         { | 
 | 1646 |             messages::internalError(asyncResp->res); | 
 | 1647 |             return; | 
 | 1648 |         } | 
 | 1649 |  | 
 | 1650 |         crow::connections::systemBus->async_method_call( | 
 | 1651 |             [asyncResp, username, password](const boost::system::error_code ec2, | 
| Patrick Williams | 59d494e | 2022-07-22 19:26:55 -0500 | [diff] [blame] | 1652 |                                             sdbusplus::message_t& m) { | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1653 |             if (ec2) | 
 | 1654 |             { | 
 | 1655 |                 userErrorMessageHandler(m.get_error(), asyncResp, username, ""); | 
 | 1656 |                 return; | 
 | 1657 |             } | 
 | 1658 |  | 
 | 1659 |             if (pamUpdatePassword(username, password) != PAM_SUCCESS) | 
 | 1660 |             { | 
 | 1661 |                 // At this point we have a user that's been | 
 | 1662 |                 // created, but the password set | 
 | 1663 |                 // failed.Something is wrong, so delete the user | 
 | 1664 |                 // that we've already created | 
 | 1665 |                 sdbusplus::message::object_path tempObjPath(rootUserDbusPath); | 
 | 1666 |                 tempObjPath /= username; | 
 | 1667 |                 const std::string userPath(tempObjPath); | 
 | 1668 |  | 
 | 1669 |                 crow::connections::systemBus->async_method_call( | 
 | 1670 |                     [asyncResp, password](const boost::system::error_code ec3) { | 
 | 1671 |                     if (ec3) | 
 | 1672 |                     { | 
 | 1673 |                         messages::internalError(asyncResp->res); | 
 | 1674 |                         return; | 
 | 1675 |                     } | 
 | 1676 |  | 
 | 1677 |                     // If password is invalid | 
 | 1678 |                     messages::propertyValueFormatError(asyncResp->res, password, | 
 | 1679 |                                                        "Password"); | 
 | 1680 |                     }, | 
 | 1681 |                     "xyz.openbmc_project.User.Manager", userPath, | 
 | 1682 |                     "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 1683 |  | 
 | 1684 |                 BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; | 
 | 1685 |                 return; | 
 | 1686 |             } | 
 | 1687 |  | 
 | 1688 |             messages::created(asyncResp->res); | 
 | 1689 |             asyncResp->res.addHeader( | 
 | 1690 |                 "Location", "/redfish/v1/AccountService/Accounts/" + username); | 
 | 1691 |             }, | 
 | 1692 |             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1693 |             "xyz.openbmc_project.User.Manager", "CreateUser", username, | 
 | 1694 |             allGroupsList, *roleId, *enabled); | 
 | 1695 |         }); | 
 | 1696 | } | 
 | 1697 |  | 
 | 1698 | inline void | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1699 |     handleAccountHead(App& app, const crow::Request& req, | 
 | 1700 |                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1701 |                       const std::string& /*accountName*/) | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1702 | { | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1703 |  | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1704 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1705 |     { | 
 | 1706 |         return; | 
 | 1707 |     } | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 1708 |     asyncResp->res.addHeader( | 
 | 1709 |         boost::beast::http::field::link, | 
 | 1710 |         "</redfish/v1/JsonSchemas/ManagerAccount/ManagerAccount.json>; rel=describedby"); | 
 | 1711 | } | 
 | 1712 | inline void | 
 | 1713 |     handleAccountGet(App& app, const crow::Request& req, | 
 | 1714 |                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1715 |                      const std::string& accountName) | 
 | 1716 | { | 
 | 1717 |     handleAccountHead(app, req, asyncResp, accountName); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1718 | #ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1719 |     // If authentication is disabled, there are no user accounts | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1720 |     messages::resourceNotFound(asyncResp->res, "ManagerAccount", accountName); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1721 |     return; | 
 | 1722 |  | 
 | 1723 | #endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1724 |     if (req.session == nullptr) | 
 | 1725 |     { | 
 | 1726 |         messages::internalError(asyncResp->res); | 
 | 1727 |         return; | 
 | 1728 |     } | 
 | 1729 |     if (req.session->username != accountName) | 
 | 1730 |     { | 
 | 1731 |         // At this point we've determined that the user is trying to | 
 | 1732 |         // modify a user that isn't them.  We need to verify that they | 
 | 1733 |         // have permissions to modify other users, so re-run the auth | 
 | 1734 |         // check with the same permissions, minus ConfigureSelf. | 
 | 1735 |         Privileges effectiveUserPrivileges = | 
 | 1736 |             redfish::getUserPrivileges(req.userRole); | 
 | 1737 |         Privileges requiredPermissionsToChangeNonSelf = {"ConfigureUsers", | 
 | 1738 |                                                          "ConfigureManager"}; | 
 | 1739 |         if (!effectiveUserPrivileges.isSupersetOf( | 
 | 1740 |                 requiredPermissionsToChangeNonSelf)) | 
 | 1741 |         { | 
 | 1742 |             BMCWEB_LOG_DEBUG << "GET Account denied access"; | 
 | 1743 |             messages::insufficientPrivilege(asyncResp->res); | 
 | 1744 |             return; | 
 | 1745 |         } | 
 | 1746 |     } | 
 | 1747 |  | 
 | 1748 |     crow::connections::systemBus->async_method_call( | 
 | 1749 |         [asyncResp, | 
 | 1750 |          accountName](const boost::system::error_code ec, | 
 | 1751 |                       const dbus::utility::ManagedObjectType& users) { | 
 | 1752 |         if (ec) | 
 | 1753 |         { | 
 | 1754 |             messages::internalError(asyncResp->res); | 
 | 1755 |             return; | 
 | 1756 |         } | 
 | 1757 |         const auto userIt = std::find_if( | 
 | 1758 |             users.begin(), users.end(), | 
 | 1759 |             [accountName]( | 
 | 1760 |                 const std::pair<sdbusplus::message::object_path, | 
 | 1761 |                                 dbus::utility::DBusInteracesMap>& user) { | 
 | 1762 |             return accountName == user.first.filename(); | 
 | 1763 |             }); | 
 | 1764 |  | 
 | 1765 |         if (userIt == users.end()) | 
 | 1766 |         { | 
 | 1767 |             messages::resourceNotFound(asyncResp->res, "ManagerAccount", | 
 | 1768 |                                        accountName); | 
 | 1769 |             return; | 
 | 1770 |         } | 
 | 1771 |  | 
 | 1772 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 1773 |             "#ManagerAccount.v1_4_0.ManagerAccount"; | 
 | 1774 |         asyncResp->res.jsonValue["Name"] = "User Account"; | 
 | 1775 |         asyncResp->res.jsonValue["Description"] = "User Account"; | 
 | 1776 |         asyncResp->res.jsonValue["Password"] = nullptr; | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1777 |  | 
 | 1778 |         for (const auto& interface : userIt->second) | 
 | 1779 |         { | 
 | 1780 |             if (interface.first == "xyz.openbmc_project.User.Attributes") | 
 | 1781 |             { | 
 | 1782 |                 for (const auto& property : interface.second) | 
 | 1783 |                 { | 
 | 1784 |                     if (property.first == "UserEnabled") | 
 | 1785 |                     { | 
 | 1786 |                         const bool* userEnabled = | 
 | 1787 |                             std::get_if<bool>(&property.second); | 
 | 1788 |                         if (userEnabled == nullptr) | 
 | 1789 |                         { | 
 | 1790 |                             BMCWEB_LOG_ERROR << "UserEnabled wasn't a bool"; | 
 | 1791 |                             messages::internalError(asyncResp->res); | 
 | 1792 |                             return; | 
 | 1793 |                         } | 
 | 1794 |                         asyncResp->res.jsonValue["Enabled"] = *userEnabled; | 
 | 1795 |                     } | 
 | 1796 |                     else if (property.first == "UserLockedForFailedAttempt") | 
 | 1797 |                     { | 
 | 1798 |                         const bool* userLocked = | 
 | 1799 |                             std::get_if<bool>(&property.second); | 
 | 1800 |                         if (userLocked == nullptr) | 
 | 1801 |                         { | 
 | 1802 |                             BMCWEB_LOG_ERROR << "UserLockedForF" | 
 | 1803 |                                                 "ailedAttempt " | 
 | 1804 |                                                 "wasn't a bool"; | 
 | 1805 |                             messages::internalError(asyncResp->res); | 
 | 1806 |                             return; | 
 | 1807 |                         } | 
 | 1808 |                         asyncResp->res.jsonValue["Locked"] = *userLocked; | 
 | 1809 |                         asyncResp->res | 
 | 1810 |                             .jsonValue["Locked@Redfish.AllowableValues"] = { | 
 | 1811 |                             "false"}; // can only unlock accounts | 
 | 1812 |                     } | 
 | 1813 |                     else if (property.first == "UserPrivilege") | 
 | 1814 |                     { | 
 | 1815 |                         const std::string* userPrivPtr = | 
 | 1816 |                             std::get_if<std::string>(&property.second); | 
 | 1817 |                         if (userPrivPtr == nullptr) | 
 | 1818 |                         { | 
 | 1819 |                             BMCWEB_LOG_ERROR << "UserPrivilege wasn't a " | 
 | 1820 |                                                 "string"; | 
 | 1821 |                             messages::internalError(asyncResp->res); | 
 | 1822 |                             return; | 
 | 1823 |                         } | 
 | 1824 |                         std::string role = getRoleIdFromPrivilege(*userPrivPtr); | 
 | 1825 |                         if (role.empty()) | 
 | 1826 |                         { | 
 | 1827 |                             BMCWEB_LOG_ERROR << "Invalid user role"; | 
 | 1828 |                             messages::internalError(asyncResp->res); | 
 | 1829 |                             return; | 
 | 1830 |                         } | 
 | 1831 |                         asyncResp->res.jsonValue["RoleId"] = role; | 
 | 1832 |  | 
 | 1833 |                         nlohmann::json& roleEntry = | 
 | 1834 |                             asyncResp->res.jsonValue["Links"]["Role"]; | 
 | 1835 |                         roleEntry["@odata.id"] = | 
 | 1836 |                             "/redfish/v1/AccountService/Roles/" + role; | 
 | 1837 |                     } | 
 | 1838 |                     else if (property.first == "UserPasswordExpired") | 
 | 1839 |                     { | 
 | 1840 |                         const bool* userPasswordExpired = | 
 | 1841 |                             std::get_if<bool>(&property.second); | 
 | 1842 |                         if (userPasswordExpired == nullptr) | 
 | 1843 |                         { | 
 | 1844 |                             BMCWEB_LOG_ERROR | 
 | 1845 |                                 << "UserPasswordExpired wasn't a bool"; | 
 | 1846 |                             messages::internalError(asyncResp->res); | 
 | 1847 |                             return; | 
 | 1848 |                         } | 
 | 1849 |                         asyncResp->res.jsonValue["PasswordChangeRequired"] = | 
 | 1850 |                             *userPasswordExpired; | 
 | 1851 |                     } | 
| Abhishek Patel | c722981 | 2022-02-01 10:07:15 -0600 | [diff] [blame] | 1852 |                     else if (property.first == "UserGroups") | 
 | 1853 |                     { | 
 | 1854 |                         const std::vector<std::string>* userGroups = | 
 | 1855 |                             std::get_if<std::vector<std::string>>( | 
 | 1856 |                                 &property.second); | 
 | 1857 |                         if (userGroups == nullptr) | 
 | 1858 |                         { | 
 | 1859 |                             BMCWEB_LOG_ERROR | 
 | 1860 |                                 << "userGroups wasn't a string vector"; | 
 | 1861 |                             messages::internalError(asyncResp->res); | 
 | 1862 |                             return; | 
 | 1863 |                         } | 
 | 1864 |                         if (!translateUserGroup(*userGroups, asyncResp->res)) | 
 | 1865 |                         { | 
 | 1866 |                             BMCWEB_LOG_ERROR << "userGroups mapping failed"; | 
 | 1867 |                             messages::internalError(asyncResp->res); | 
 | 1868 |                             return; | 
 | 1869 |                         } | 
 | 1870 |                     } | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1871 |                 } | 
 | 1872 |             } | 
 | 1873 |         } | 
 | 1874 |  | 
 | 1875 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 1876 |             "/redfish/v1/AccountService/Accounts/" + accountName; | 
 | 1877 |         asyncResp->res.jsonValue["Id"] = accountName; | 
 | 1878 |         asyncResp->res.jsonValue["UserName"] = accountName; | 
 | 1879 |         }, | 
 | 1880 |         "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 1881 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 1882 | } | 
 | 1883 |  | 
 | 1884 | inline void | 
 | 1885 |     handleAccounttDelete(App& app, const crow::Request& req, | 
 | 1886 |                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1887 |                          const std::string& username) | 
 | 1888 | { | 
 | 1889 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1890 |     { | 
 | 1891 |         return; | 
 | 1892 |     } | 
 | 1893 |  | 
 | 1894 | #ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1895 |     // If authentication is disabled, there are no user accounts | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1896 |     messages::resourceNotFound(asyncResp->res, "ManagerAccount", username); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1897 |     return; | 
 | 1898 |  | 
 | 1899 | #endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1900 |     sdbusplus::message::object_path tempObjPath(rootUserDbusPath); | 
 | 1901 |     tempObjPath /= username; | 
 | 1902 |     const std::string userPath(tempObjPath); | 
 | 1903 |  | 
 | 1904 |     crow::connections::systemBus->async_method_call( | 
 | 1905 |         [asyncResp, username](const boost::system::error_code ec) { | 
 | 1906 |         if (ec) | 
 | 1907 |         { | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1908 |             messages::resourceNotFound(asyncResp->res, "ManagerAccount", | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1909 |                                        username); | 
 | 1910 |             return; | 
 | 1911 |         } | 
 | 1912 |  | 
 | 1913 |         messages::accountRemoved(asyncResp->res); | 
 | 1914 |         }, | 
 | 1915 |         "xyz.openbmc_project.User.Manager", userPath, | 
 | 1916 |         "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 1917 | } | 
 | 1918 |  | 
 | 1919 | inline void | 
 | 1920 |     handleAccountPatch(App& app, const crow::Request& req, | 
 | 1921 |                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1922 |                        const std::string& username) | 
 | 1923 | { | 
 | 1924 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 1925 |     { | 
 | 1926 |         return; | 
 | 1927 |     } | 
 | 1928 | #ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1929 |     // If authentication is disabled, there are no user accounts | 
| Jiaqing Zhao | d8a5d5d | 2022-08-05 16:21:51 +0800 | [diff] [blame] | 1930 |     messages::resourceNotFound(asyncResp->res, "ManagerAccount", username); | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1931 |     return; | 
 | 1932 |  | 
 | 1933 | #endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION | 
 | 1934 |     std::optional<std::string> newUserName; | 
 | 1935 |     std::optional<std::string> password; | 
 | 1936 |     std::optional<bool> enabled; | 
 | 1937 |     std::optional<std::string> roleId; | 
 | 1938 |     std::optional<bool> locked; | 
 | 1939 |  | 
 | 1940 |     if (req.session == nullptr) | 
 | 1941 |     { | 
 | 1942 |         messages::internalError(asyncResp->res); | 
 | 1943 |         return; | 
 | 1944 |     } | 
 | 1945 |  | 
 | 1946 |     Privileges effectiveUserPrivileges = | 
 | 1947 |         redfish::getUserPrivileges(req.userRole); | 
 | 1948 |     Privileges configureUsers = {"ConfigureUsers"}; | 
 | 1949 |     bool userHasConfigureUsers = | 
 | 1950 |         effectiveUserPrivileges.isSupersetOf(configureUsers); | 
 | 1951 |     if (userHasConfigureUsers) | 
 | 1952 |     { | 
 | 1953 |         // Users with ConfigureUsers can modify for all users | 
 | 1954 |         if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", | 
 | 1955 |                                       newUserName, "Password", password, | 
 | 1956 |                                       "RoleId", roleId, "Enabled", enabled, | 
 | 1957 |                                       "Locked", locked)) | 
 | 1958 |         { | 
 | 1959 |             return; | 
 | 1960 |         } | 
 | 1961 |     } | 
 | 1962 |     else | 
 | 1963 |     { | 
 | 1964 |         // ConfigureSelf accounts can only modify their own account | 
 | 1965 |         if (username != req.session->username) | 
 | 1966 |         { | 
 | 1967 |             messages::insufficientPrivilege(asyncResp->res); | 
 | 1968 |             return; | 
 | 1969 |         } | 
 | 1970 |  | 
 | 1971 |         // ConfigureSelf accounts can only modify their password | 
 | 1972 |         if (!json_util::readJsonPatch(req, asyncResp->res, "Password", | 
 | 1973 |                                       password)) | 
 | 1974 |         { | 
 | 1975 |             return; | 
 | 1976 |         } | 
 | 1977 |     } | 
 | 1978 |  | 
 | 1979 |     // if user name is not provided in the patch method or if it | 
 | 1980 |     // matches the user name in the URI, then we are treating it as | 
 | 1981 |     // updating user properties other then username. If username | 
 | 1982 |     // provided doesn't match the URI, then we are treating this as | 
 | 1983 |     // user rename request. | 
 | 1984 |     if (!newUserName || (newUserName.value() == username)) | 
 | 1985 |     { | 
 | 1986 |         updateUserProperties(asyncResp, username, password, enabled, roleId, | 
 | 1987 |                              locked); | 
 | 1988 |         return; | 
 | 1989 |     } | 
 | 1990 |     crow::connections::systemBus->async_method_call( | 
 | 1991 |         [asyncResp, username, password(std::move(password)), | 
 | 1992 |          roleId(std::move(roleId)), enabled, newUser{std::string(*newUserName)}, | 
| Patrick Williams | 59d494e | 2022-07-22 19:26:55 -0500 | [diff] [blame] | 1993 |          locked](const boost::system::error_code ec, sdbusplus::message_t& m) { | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 1994 |         if (ec) | 
 | 1995 |         { | 
 | 1996 |             userErrorMessageHandler(m.get_error(), asyncResp, newUser, | 
 | 1997 |                                     username); | 
 | 1998 |             return; | 
 | 1999 |         } | 
 | 2000 |  | 
 | 2001 |         updateUserProperties(asyncResp, newUser, password, enabled, roleId, | 
 | 2002 |                              locked); | 
 | 2003 |         }, | 
 | 2004 |         "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", | 
 | 2005 |         "xyz.openbmc_project.User.Manager", "RenameUser", username, | 
 | 2006 |         *newUserName); | 
 | 2007 | } | 
 | 2008 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2009 | inline void requestAccountServiceRoutes(App& app) | 
| Ed Tanous | b9b2e0b | 2018-09-13 13:47:50 -0700 | [diff] [blame] | 2010 | { | 
| Ed Tanous | b9b2e0b | 2018-09-13 13:47:50 -0700 | [diff] [blame] | 2011 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2012 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/") | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 2013 |         .privileges(redfish::privileges::headAccountService) | 
 | 2014 |         .methods(boost::beast::http::verb::head)( | 
 | 2015 |             std::bind_front(handleAccountServiceHead, std::ref(app))); | 
 | 2016 |  | 
 | 2017 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2018 |         .privileges(redfish::privileges::getAccountService) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2019 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2020 |             std::bind_front(handleAccountServiceGet, std::ref(app))); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2021 |  | 
| Ed Tanous | f5ffd80 | 2021-07-19 10:55:33 -0700 | [diff] [blame] | 2022 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/") | 
| Gunnar Mills | 1ec43ee | 2022-01-04 15:39:52 -0600 | [diff] [blame] | 2023 |         .privileges(redfish::privileges::patchAccountService) | 
| Ed Tanous | f5ffd80 | 2021-07-19 10:55:33 -0700 | [diff] [blame] | 2024 |         .methods(boost::beast::http::verb::patch)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2025 |             std::bind_front(handleAccountServicePatch, std::ref(app))); | 
| Ed Tanous | f5ffd80 | 2021-07-19 10:55:33 -0700 | [diff] [blame] | 2026 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2027 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/") | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 2028 |         .privileges(redfish::privileges::headManagerAccountCollection) | 
 | 2029 |         .methods(boost::beast::http::verb::head)( | 
 | 2030 |             std::bind_front(handleAccountCollectionHead, std::ref(app))); | 
 | 2031 |  | 
 | 2032 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2033 |         .privileges(redfish::privileges::getManagerAccountCollection) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2034 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2035 |             std::bind_front(handleAccountCollectionGet, std::ref(app))); | 
| Ed Tanous | 06e086d | 2018-09-19 17:19:52 -0700 | [diff] [blame] | 2036 |  | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2037 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2038 |         .privileges(redfish::privileges::postManagerAccountCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2039 |         .methods(boost::beast::http::verb::post)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2040 |             std::bind_front(handleAccountCollectionPost, std::ref(app))); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2041 |  | 
 | 2042 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/") | 
| Ed Tanous | 4c7d4d3 | 2022-07-07 15:29:35 -0700 | [diff] [blame] | 2043 |         .privileges(redfish::privileges::headManagerAccount) | 
 | 2044 |         .methods(boost::beast::http::verb::head)( | 
 | 2045 |             std::bind_front(handleAccountHead, std::ref(app))); | 
 | 2046 |  | 
 | 2047 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/") | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2048 |         .privileges(redfish::privileges::getManagerAccount) | 
 | 2049 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2050 |             std::bind_front(handleAccountGet, std::ref(app))); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2051 |  | 
 | 2052 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2053 |         // TODO this privilege should be using the generated endpoints, but | 
 | 2054 |         // because of the special handling of ConfigureSelf, it's not able to | 
 | 2055 |         // yet | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2056 |         .privileges({{"ConfigureUsers"}, {"ConfigureSelf"}}) | 
 | 2057 |         .methods(boost::beast::http::verb::patch)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2058 |             std::bind_front(handleAccountPatch, std::ref(app))); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2059 |  | 
 | 2060 |     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2061 |         .privileges(redfish::privileges::deleteManagerAccount) | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2062 |         .methods(boost::beast::http::verb::delete_)( | 
| Ed Tanous | 1ef4c34 | 2022-05-12 16:12:36 -0700 | [diff] [blame] | 2063 |             std::bind_front(handleAccounttDelete, std::ref(app))); | 
| Ed Tanous | 6c51eab | 2021-06-03 12:30:29 -0700 | [diff] [blame] | 2064 | } | 
| Lewanczyk, Dawid | 88d16c9 | 2018-02-02 14:51:09 +0100 | [diff] [blame] | 2065 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 2066 | } // namespace redfish |