2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
18 * Security Manager library header
21 * @file client-security-manager.cpp
22 * @author Pawel Polawski <p.polawski@samsung.com>
23 * @author Rafal Krypa <r.krypa@samsung.com>
25 * @brief This file contain client side implementation of security-manager API
36 #include <sys/types.h>
38 #include <sys/xattr.h>
39 #include <sys/smack.h>
40 #include <sys/capability.h>
42 #include <dpl/log/log.h>
43 #include <dpl/exception.h>
44 #include <smack-labels.h>
45 #include <message-buffer.h>
46 #include <client-common.h>
47 #include <protocols.h>
48 #include <service_impl.h>
49 #include <connection.h>
50 #include <zone-utils.h>
52 #include <security-manager.h>
53 #include <client-offline.h>
55 static const char *EMPTY = "";
58 * Mapping of lib_retcode error codes to theirs strings equivalents
60 static std::map<enum lib_retcode, std::string> lib_retcode_string_map = {
61 {SECURITY_MANAGER_SUCCESS, "Success"},
62 {SECURITY_MANAGER_ERROR_UNKNOWN, "Unknown error"},
63 {SECURITY_MANAGER_ERROR_INPUT_PARAM, "Invalid function parameter was given"},
64 {SECURITY_MANAGER_ERROR_MEMORY, "Memory allocation error"},
65 {SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, "Incomplete data in application request"},
66 {SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "User does not have sufficient "
67 "rigths to perform an operation"},
68 {SECURITY_MANAGER_ERROR_ACCESS_DENIED, "Insufficient privileges"},
72 const char *security_manager_strerror(enum lib_retcode rc)
75 return lib_retcode_string_map.at(rc).c_str();
76 } catch (const std::out_of_range &e) {
77 return "Unknown error code";
82 int security_manager_app_inst_req_new(app_inst_req **pp_req)
85 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
88 *pp_req = new app_inst_req;
89 } catch (std::bad_alloc& ex) {
90 return SECURITY_MANAGER_ERROR_MEMORY;
92 (*pp_req)->uid = geteuid();
94 return SECURITY_MANAGER_SUCCESS;
98 void security_manager_app_inst_req_free(app_inst_req *p_req)
104 int security_manager_app_inst_req_set_uid(app_inst_req *p_req,
108 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
112 return SECURITY_MANAGER_SUCCESS;
116 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
118 if (!p_req || !app_id)
119 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
121 p_req->appId = app_id;
123 return SECURITY_MANAGER_SUCCESS;
127 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
129 if (!p_req || !pkg_id)
130 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
132 p_req->pkgId = pkg_id;
134 return SECURITY_MANAGER_SUCCESS;
138 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
140 if (!p_req || !privilege)
141 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
143 p_req->privileges.push_back(privilege);
145 return SECURITY_MANAGER_SUCCESS;
149 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
151 if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
152 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
154 p_req->appPaths.push_back(std::make_pair(path, path_type));
156 return SECURITY_MANAGER_SUCCESS;
160 int security_manager_app_install(const app_inst_req *p_req)
162 using namespace SecurityManager;
164 return try_catch([&] {
165 //checking parameters
167 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
168 if (p_req->appId.empty() || p_req->pkgId.empty())
169 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
172 ClientOffline offlineMode;
173 if (offlineMode.isOffline()) {
174 retval = SecurityManager::ServiceImpl().appInstall(*p_req, geteuid(), false);
176 MessageBuffer send, recv;
178 //put data into buffer
179 Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL,
180 p_req->appId, p_req->pkgId, p_req->privileges, p_req->appPaths, p_req->uid);
182 //send buffer to server
183 retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
184 if (retval != SECURITY_MANAGER_API_SUCCESS) {
185 LogError("Error in sendToServer. Error code: " << retval);
186 return SECURITY_MANAGER_ERROR_UNKNOWN;
189 //receive response from server
190 Deserialization::Deserialize(recv, retval);
193 case SECURITY_MANAGER_API_SUCCESS:
194 return SECURITY_MANAGER_SUCCESS;
195 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
196 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
197 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
198 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
199 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
200 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
202 return SECURITY_MANAGER_ERROR_UNKNOWN;
209 int security_manager_app_uninstall(const app_inst_req *p_req)
211 using namespace SecurityManager;
212 MessageBuffer send, recv;
214 return try_catch([&] {
215 //checking parameters
217 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
218 if (p_req->appId.empty())
219 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
221 //put data into buffer
222 Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL,
225 //send buffer to server
226 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
227 if (retval != SECURITY_MANAGER_API_SUCCESS) {
228 LogError("Error in sendToServer. Error code: " << retval);
229 return SECURITY_MANAGER_ERROR_UNKNOWN;
232 //receive response from server
233 Deserialization::Deserialize(recv, retval);
234 if (retval != SECURITY_MANAGER_API_SUCCESS)
235 return SECURITY_MANAGER_ERROR_UNKNOWN;
237 return SECURITY_MANAGER_SUCCESS;;
242 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
244 using namespace SecurityManager;
245 MessageBuffer send, recv;
247 LogDebug("security_manager_get_app_pkgid() called");
249 return try_catch([&] {
250 //checking parameters
252 if (app_id == NULL) {
253 LogError("security_manager_app_get_pkgid: app_id is NULL");
254 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
257 if (pkg_id == NULL) {
258 LogError("security_manager_app_get_pkgid: pkg_id is NULL");
259 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
262 //put data into buffer
263 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID),
264 std::string(app_id));
266 //send buffer to server
267 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
268 if (retval != SECURITY_MANAGER_API_SUCCESS) {
269 LogDebug("Error in sendToServer. Error code: " << retval);
270 return SECURITY_MANAGER_ERROR_UNKNOWN;
273 //receive response from server
274 Deserialization::Deserialize(recv, retval);
275 if (retval != SECURITY_MANAGER_API_SUCCESS)
276 return SECURITY_MANAGER_ERROR_UNKNOWN;
278 std::string pkgIdString;
279 Deserialization::Deserialize(recv, pkgIdString);
280 if (pkgIdString.empty()) {
281 LogError("Unexpected empty pkgId");
282 return SECURITY_MANAGER_ERROR_UNKNOWN;
285 *pkg_id = strdup(pkgIdString.c_str());
286 if (*pkg_id == NULL) {
287 LogError("Failed to allocate memory for pkgId");
288 return SECURITY_MANAGER_ERROR_MEMORY;
291 return SECURITY_MANAGER_SUCCESS;
295 static bool setup_smack(const char *label)
297 int labelSize = strlen(label);
299 // Set Smack label for open socket file descriptors
301 std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
302 opendir("/proc/self/fd"), closedir);
304 LogError("Unable to read list of open file descriptors: " <<
306 return SECURITY_MANAGER_ERROR_UNKNOWN;
311 struct dirent *dirEntry = readdir(dir.get());
312 if (dirEntry == nullptr) {
313 if (errno == 0) // NULL return value also signals end of directory
316 LogError("Unable to read list of open file descriptors: " <<
318 return SECURITY_MANAGER_ERROR_UNKNOWN;
321 // Entries with numerical names specify file descriptors, ignore the rest
322 if (!isdigit(dirEntry->d_name[0]))
326 int fd = atoi(dirEntry->d_name);
327 int ret = fstat(fd, &statBuf);
329 LogWarning("fstat failed on file descriptor " << fd << ": " <<
333 if (S_ISSOCK(statBuf.st_mode)) {
334 ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
336 LogError("Setting Smack label failed on file descriptor " <<
337 fd << ": " << strerror(errno));
338 return SECURITY_MANAGER_ERROR_UNKNOWN;
341 ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
343 LogError("Setting Smack label failed on file descriptor " <<
344 fd << ": " << strerror(errno));
345 return SECURITY_MANAGER_ERROR_UNKNOWN;
350 // Set Smack label of current process
351 smack_set_label_for_self(label);
353 return SECURITY_MANAGER_SUCCESS;
357 int security_manager_set_process_label_from_appid(const char *app_id)
360 std::string appLabel;
362 LogDebug("security_manager_set_process_label_from_appid() called");
364 if (smack_smackfs_path() == NULL)
365 return SECURITY_MANAGER_SUCCESS;
367 // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
370 if (!getZoneIdFromPid(getpid(), zoneId)) {
371 LogError("Failed to get ID of zone");
372 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
376 appLabel = SecurityManager::zoneSmackLabelGenerate(
377 SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
380 LogError("Failed to generate smack label for appId: " << app_id);
381 return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
384 if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
385 LogError("Failed to set smack label " << appLabel << " for current process");
389 return SECURITY_MANAGER_SUCCESS;
393 int security_manager_set_process_groups_from_appid(const char *app_id)
395 using namespace SecurityManager;
396 MessageBuffer send, recv;
399 LogDebug("security_manager_set_process_groups_from_appid() called");
401 return try_catch([&] {
402 //checking parameters
404 if (app_id == nullptr) {
405 LogError("app_id is NULL");
406 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
409 //put data into buffer
410 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS),
411 std::string(app_id));
413 //send buffer to server
414 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
415 if (retval != SECURITY_MANAGER_API_SUCCESS) {
416 LogDebug("Error in sendToServer. Error code: " << retval);
417 return SECURITY_MANAGER_ERROR_UNKNOWN;
420 //receive response from server
421 Deserialization::Deserialize(recv, retval);
422 if (retval != SECURITY_MANAGER_API_SUCCESS) {
423 LogError("Failed to get list of groups from security-manager service. Error code: " << retval);
424 return SECURITY_MANAGER_ERROR_UNKNOWN;
427 //How many new groups?
429 Deserialization::Deserialize(recv, newGroupsCnt);
431 //And how many groups do we belong to already?
433 ret = getgroups(0, nullptr);
435 LogError("Unable to get list of current supplementary groups: " <<
437 return SECURITY_MANAGER_ERROR_UNKNOWN;
441 //Allocate an array for both old and new groups gids
442 std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
444 LogError("Memory allocation failed.");
445 return SECURITY_MANAGER_ERROR_MEMORY;
448 //Get the old groups from process
449 ret = getgroups(oldGroupsCnt, groups.get());
451 LogError("Unable to get list of current supplementary groups: " <<
453 return SECURITY_MANAGER_ERROR_UNKNOWN;
456 //Get the new groups from server response
457 for (int i = 0; i < newGroupsCnt; ++i) {
459 Deserialization::Deserialize(recv, gid);
460 groups.get()[oldGroupsCnt + i] = gid;
461 LogDebug("Adding process to group " << gid);
464 //Apply the modified groups list
465 ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
467 LogError("Unable to get list of current supplementary groups: " <<
469 return SECURITY_MANAGER_ERROR_UNKNOWN;
472 return SECURITY_MANAGER_SUCCESS;
477 int security_manager_drop_process_privileges(void)
479 LogDebug("security_manager_drop_process_privileges() called");
482 cap_t cap = cap_init();
484 LogError("Unable to allocate capability object");
485 return SECURITY_MANAGER_ERROR_MEMORY;
488 ret = cap_clear(cap);
490 LogError("Unable to initialize capability object");
492 return SECURITY_MANAGER_ERROR_UNKNOWN;
495 ret = cap_set_proc(cap);
497 LogError("Unable to drop process capabilities");
499 return SECURITY_MANAGER_ERROR_UNKNOWN;
503 return SECURITY_MANAGER_SUCCESS;
507 int security_manager_prepare_app(const char *app_id)
509 LogDebug("security_manager_prepare_app() called");
512 ret = security_manager_set_process_label_from_appid(app_id);
513 if (ret != SECURITY_MANAGER_SUCCESS)
516 ret = security_manager_set_process_groups_from_appid(app_id);
517 if (ret != SECURITY_MANAGER_SUCCESS) {
518 LogWarning("Unable to setup process groups for application. Privileges with direct access to resources will not work.");
519 ret = SECURITY_MANAGER_SUCCESS;
522 ret = security_manager_drop_process_privileges();
527 int security_manager_user_req_new(user_req **pp_req)
530 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
532 *pp_req = new user_req;
533 } catch (std::bad_alloc& ex) {
534 return SECURITY_MANAGER_ERROR_MEMORY;
536 return SECURITY_MANAGER_SUCCESS;
540 void security_manager_user_req_free(user_req *p_req)
546 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
549 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
553 return SECURITY_MANAGER_SUCCESS;
557 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
560 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
562 p_req->utype = static_cast<int>(utype);
564 return SECURITY_MANAGER_SUCCESS;
568 int security_manager_user_add(const user_req *p_req)
570 using namespace SecurityManager;
572 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
574 return try_catch([&] {
576 ClientOffline offlineMode;
577 if (offlineMode.isOffline()) {
578 retval = SecurityManager::ServiceImpl().userAdd(p_req->uid, p_req->utype, geteuid(),
581 MessageBuffer send, recv;
584 //put data into buffer
585 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD),
586 p_req->uid, p_req->utype);
588 //send buffer to server
589 retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
590 if (retval != SECURITY_MANAGER_API_SUCCESS) {
591 LogError("Error in sendToServer. Error code: " << retval);
592 return SECURITY_MANAGER_ERROR_UNKNOWN;
595 //receive response from server
596 Deserialization::Deserialize(recv, retval);
599 case SECURITY_MANAGER_API_SUCCESS:
600 return SECURITY_MANAGER_SUCCESS;
601 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
602 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
604 return SECURITY_MANAGER_ERROR_UNKNOWN;
610 int security_manager_user_delete(const user_req *p_req)
612 using namespace SecurityManager;
613 MessageBuffer send, recv;
615 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
616 return try_catch([&] {
618 //put data into buffer
619 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE),
622 //send buffer to server
623 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
624 if (retval != SECURITY_MANAGER_API_SUCCESS) {
625 LogError("Error in sendToServer. Error code: " << retval);
626 return SECURITY_MANAGER_ERROR_UNKNOWN;
629 //receive response from server
630 Deserialization::Deserialize(recv, retval);
632 case SECURITY_MANAGER_API_SUCCESS:
633 return SECURITY_MANAGER_SUCCESS;
634 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
635 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
637 return SECURITY_MANAGER_ERROR_UNKNOWN;
643 /***************************POLICY***************************************/
646 int security_manager_policy_update_req_new(policy_update_req **pp_req)
649 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
652 *pp_req = new policy_update_req;
653 } catch (std::bad_alloc& ex) {
654 return SECURITY_MANAGER_ERROR_MEMORY;
657 return SECURITY_MANAGER_SUCCESS;
661 void security_manager_policy_update_req_free(policy_update_req *p_req)
667 int security_manager_policy_update_send(policy_update_req *p_req)
669 using namespace SecurityManager;
670 MessageBuffer send, recv;
672 if (p_req == nullptr || p_req->units.size() == 0)
673 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
675 return try_catch([&] {
677 //put request into buffer
678 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE),
682 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
683 if (retval != SECURITY_MANAGER_API_SUCCESS) {
684 LogError("Error in sendToServer. Error code: " << retval);
685 return SECURITY_MANAGER_ERROR_UNKNOWN;
688 //receive response from server
689 Deserialization::Deserialize(recv, retval);
691 case SECURITY_MANAGER_API_SUCCESS:
692 return SECURITY_MANAGER_SUCCESS;
693 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
694 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
695 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
696 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
698 return SECURITY_MANAGER_ERROR_UNKNOWN;
703 static inline int security_manager_get_policy_internal(
704 SecurityManager::SecurityModuleCall call_type,
705 policy_entry *p_filter,
706 policy_entry ***ppp_privs_policy,
709 using namespace SecurityManager;
710 MessageBuffer send, recv;
712 if (ppp_privs_policy == nullptr
714 || p_filter == nullptr)
715 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
717 return try_catch([&] {
718 //put request into buffer
719 Serialization::Serialize(send, static_cast<int>(call_type),
723 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
724 if (retval != SECURITY_MANAGER_API_SUCCESS) {
725 LogError("Error in sendToServer. Error code: " << retval);
726 return SECURITY_MANAGER_ERROR_UNKNOWN;
728 //receive response from server
729 Deserialization::Deserialize(recv, retval);
731 case SECURITY_MANAGER_API_SUCCESS: {
732 //extract and allocate buffers for privs policy entries
734 policy_entry **entries = nullptr;
736 Deserialization::Deserialize(recv, entriesCnt);
737 entries = new policy_entry*[entriesCnt]();
738 for (int i = 0; i < entriesCnt; ++i) {
739 entries[i] = new policy_entry;
740 Deserialization::Deserialize(recv, entries[i]);
743 LogError("Error while parsing server response");
744 for (int i = 0; i < entriesCnt; ++i)
747 return SECURITY_MANAGER_ERROR_UNKNOWN;
749 *p_size = entriesCnt;
750 *ppp_privs_policy = entries;
751 return SECURITY_MANAGER_SUCCESS;
753 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
754 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
756 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
757 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
760 return SECURITY_MANAGER_ERROR_UNKNOWN;
766 int security_manager_get_configured_policy_for_admin(
767 policy_entry *p_filter,
768 policy_entry ***ppp_privs_policy,
771 return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
775 int security_manager_get_configured_policy_for_self(
776 policy_entry *p_filter,
777 policy_entry ***ppp_privs_policy,
780 return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
784 int security_manager_get_policy(
785 policy_entry *p_filter,
786 policy_entry ***ppp_privs_policy,
789 return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
793 int security_manager_policy_entry_new(policy_entry **p_entry)
796 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
799 *p_entry = new policy_entry;
800 } catch (std::bad_alloc& ex) {
801 return SECURITY_MANAGER_ERROR_MEMORY;
804 return SECURITY_MANAGER_SUCCESS;
808 void security_manager_policy_entry_free(policy_entry *p_entry)
814 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
817 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
818 p_entry->appId = app_id;
819 return SECURITY_MANAGER_SUCCESS;
823 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
826 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
827 p_entry->user = user;
828 return SECURITY_MANAGER_SUCCESS;
832 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
835 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
836 p_entry->privilege = privilege;
837 return SECURITY_MANAGER_SUCCESS;
841 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
844 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
845 p_entry->currentLevel = policy_level;
846 p_entry->maxLevel = EMPTY;
847 return SECURITY_MANAGER_SUCCESS;
851 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
854 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
855 p_entry->maxLevel = policy_level;
856 p_entry->currentLevel = EMPTY;
857 return SECURITY_MANAGER_SUCCESS;
861 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
863 if (!p_entry || !p_req)
864 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
865 p_req->units.push_back(p_entry);
867 return SECURITY_MANAGER_SUCCESS;
871 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
873 return p_entry ? p_entry->user.c_str() : nullptr;
877 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
879 return p_entry ? p_entry->appId.c_str() : nullptr;
882 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
884 return p_entry ? p_entry->privilege.c_str() : nullptr;
887 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
889 return p_entry ? p_entry->currentLevel.c_str() : nullptr;
893 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
895 return p_entry ? p_entry->maxLevel.c_str() : nullptr;
899 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
901 for (size_t i = 0; i < size; i++) {
902 delete &p_entries[i];
908 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
910 using namespace SecurityManager;
911 MessageBuffer send, recv;
912 if (!levels || !levels_count)
913 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
914 return try_catch([&] {
916 //put data into buffer
917 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
919 //send buffer to server
920 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
921 if (retval != SECURITY_MANAGER_API_SUCCESS) {
922 LogError("Error in sendToServer. Error code: " << retval);
923 return SECURITY_MANAGER_ERROR_UNKNOWN;
926 //receive response from server
927 Deserialization::Deserialize(recv, retval);
930 case SECURITY_MANAGER_API_SUCCESS:
931 // success - continue
933 case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
934 return SECURITY_MANAGER_ERROR_MEMORY;
935 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
936 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
938 return SECURITY_MANAGER_ERROR_UNKNOWN;
942 Deserialization::Deserialize(recv, count);
943 *levels_count = count;
944 LogInfo("Number of policy descriptions: " << *levels_count);
946 char **array = new char *[*levels_count];
948 for (unsigned int i = 0; i < *levels_count; ++i) {
950 Deserialization::Deserialize(recv, level);
953 LogError("Unexpected empty level");
954 return SECURITY_MANAGER_ERROR_UNKNOWN;
957 array[i] = strdup(level.c_str());
958 if (array[i] == nullptr)
959 return SECURITY_MANAGER_ERROR_MEMORY;
964 return SECURITY_MANAGER_SUCCESS;
969 void security_manager_policy_levels_free(char **levels, size_t levels_count)
971 for (unsigned int i = 0; i < levels_count; i++)
977 lib_retcode get_privileges_mapping(const std::string &from_version,
978 const std::string &to_version,
979 const std::vector<std::string> &privileges,
980 char ***privileges_mappings,
981 size_t *mappings_count)
983 using namespace SecurityManager;
984 MessageBuffer send, recv;
985 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GET_PRIVILEGES_MAPPING));
986 Serialization::Serialize(send, from_version);
987 Serialization::Serialize(send, to_version);
988 Serialization::Serialize(send, privileges);
990 //send buffer to server
991 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
992 if (retval != SECURITY_MANAGER_API_SUCCESS) {
993 LogError("Error in sendToServer. Error code: " << retval);
994 return SECURITY_MANAGER_ERROR_UNKNOWN;
997 //receive response from server
998 Deserialization::Deserialize(recv, retval);
1001 case SECURITY_MANAGER_API_SUCCESS:
1002 // success - continue
1004 case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1005 return SECURITY_MANAGER_ERROR_MEMORY;
1006 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1007 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1009 return SECURITY_MANAGER_ERROR_UNKNOWN;
1013 Deserialization::Deserialize(recv, count);
1014 LogInfo("Number of privilege mappings: " << count);
1016 auto free_mapping = std::bind(security_manager_privilege_mapping_free,
1017 std::placeholders::_1, std::ref(i));
1018 std::unique_ptr<char *[], decltype (free_mapping)> mappings_ptr(new char *[count], free_mapping);
1020 for (; i < count; ++i) {
1021 std::string privilege_mapping;
1022 Deserialization::Deserialize(recv, privilege_mapping);
1023 if (privilege_mapping.empty()) {
1024 LogError("Unexpected empty privilege mapping");
1025 return SECURITY_MANAGER_ERROR_UNKNOWN;
1028 mappings_ptr.get()[i] = strdup(privilege_mapping.c_str());
1029 if (mappings_ptr.get()[i] == nullptr)
1030 return SECURITY_MANAGER_ERROR_MEMORY;
1033 *privileges_mappings = mappings_ptr.release();
1034 *mappings_count = count;
1036 return SECURITY_MANAGER_SUCCESS;
1039 SECURITY_MANAGER_API
1040 int security_manager_get_privileges_mapping(const char *from_version,
1041 const char *to_version,
1042 char const * const *privileges,
1043 size_t privileges_count,
1044 char ***privileges_mappings,
1045 size_t *mappings_count)
1047 if (from_version == nullptr || privileges_mappings == nullptr || mappings_count == nullptr) {
1048 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1050 return try_catch([&] {
1051 std::vector<std::string> privilegesToMap;
1052 if (privileges != nullptr) {
1053 privilegesToMap.reserve(privileges_count);
1054 privilegesToMap.insert(privilegesToMap.end(), privileges, privileges + privileges_count);
1056 if (to_version == nullptr)
1058 LogDebug("security_manager_get_privileges_mapping() called with :"
1059 " from_version = " << from_version << " to_version = " << to_version <<
1060 " privileges_count " << privilegesToMap.size());
1062 return get_privileges_mapping(from_version, to_version, privilegesToMap,
1063 privileges_mappings, mappings_count);
1067 SECURITY_MANAGER_API
1068 void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
1070 for(size_t i = 0; i < mappings_count; i++)
1071 free(privileges_mappings[i]);
1072 delete [] privileges_mappings;
1075 SECURITY_MANAGER_API
1076 int security_manager_groups_get(char ***groups, size_t *groups_count)
1078 using namespace SecurityManager;
1079 MessageBuffer send, recv;
1080 if (!groups || !groups_count)
1081 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1082 return try_catch([&] {
1084 //put data into buffer
1085 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GROUPS_GET));
1087 //send buffer to server
1088 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
1089 if (retval != SECURITY_MANAGER_API_SUCCESS) {
1090 LogError("Error in sendToServer. Error code: " << retval);
1091 return SECURITY_MANAGER_ERROR_UNKNOWN;
1094 //receive response from server
1095 Deserialization::Deserialize(recv, retval);
1098 case SECURITY_MANAGER_API_SUCCESS:
1099 // success - continue
1101 case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1102 return SECURITY_MANAGER_ERROR_MEMORY;
1103 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1104 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1106 return SECURITY_MANAGER_ERROR_UNKNOWN;
1109 std::vector<std::string> vgroups;
1110 Deserialization::Deserialize(recv, vgroups);
1111 const auto vgroups_size = vgroups.size();
1112 LogInfo("Number of groups: " << vgroups_size);
1114 std::unique_ptr<char *, std::function<void(char **)>> array(
1115 static_cast<char **>(calloc(vgroups_size, sizeof(char *))),
1116 std::bind(security_manager_groups_free, std::placeholders::_1, vgroups_size));
1118 if (array == nullptr)
1119 return SECURITY_MANAGER_ERROR_MEMORY;
1121 for (size_t i = 0; i < vgroups_size; ++i) {
1122 const auto &group = vgroups.at(i);
1124 if (group.empty()) {
1125 LogError("Unexpected empty group");
1126 return SECURITY_MANAGER_ERROR_UNKNOWN;
1129 array.get()[i] = strdup(group.c_str());
1130 if (array.get()[i] == nullptr)
1131 return SECURITY_MANAGER_ERROR_MEMORY;
1134 *groups_count = vgroups_size;
1135 *groups = array.release();
1137 return SECURITY_MANAGER_SUCCESS;
1141 SECURITY_MANAGER_API
1142 void security_manager_groups_free(char **groups, size_t groups_count)
1144 if (groups == nullptr)
1147 for (size_t i = 0; i < groups_count; i++)