2 * Copyright (c) 2000 - 2014 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 Serialization::Serialize(send, p_req->appId);
181 Serialization::Serialize(send, p_req->pkgId);
182 Serialization::Serialize(send, p_req->privileges);
183 Serialization::Serialize(send, p_req->appPaths);
184 Serialization::Serialize(send, p_req->uid);
186 //send buffer to server
187 retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
188 if (retval != SECURITY_MANAGER_API_SUCCESS) {
189 LogError("Error in sendToServer. Error code: " << retval);
190 return SECURITY_MANAGER_ERROR_UNKNOWN;
193 //receive response from server
194 Deserialization::Deserialize(recv, retval);
197 case SECURITY_MANAGER_API_SUCCESS:
198 return SECURITY_MANAGER_SUCCESS;
199 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
200 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
201 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
202 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
203 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
204 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
206 return SECURITY_MANAGER_ERROR_UNKNOWN;
213 int security_manager_app_uninstall(const app_inst_req *p_req)
215 using namespace SecurityManager;
216 MessageBuffer send, recv;
218 return try_catch([&] {
219 //checking parameters
221 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
222 if (p_req->appId.empty())
223 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
225 //put data into buffer
226 Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
227 Serialization::Serialize(send, p_req->appId);
229 //send buffer to server
230 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
231 if (retval != SECURITY_MANAGER_API_SUCCESS) {
232 LogError("Error in sendToServer. Error code: " << retval);
233 return SECURITY_MANAGER_ERROR_UNKNOWN;
236 //receive response from server
237 Deserialization::Deserialize(recv, retval);
238 if (retval != SECURITY_MANAGER_API_SUCCESS)
239 return SECURITY_MANAGER_ERROR_UNKNOWN;
241 return SECURITY_MANAGER_SUCCESS;;
246 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
248 using namespace SecurityManager;
249 MessageBuffer send, recv;
251 LogDebug("security_manager_get_app_pkgid() called");
253 return try_catch([&] {
254 //checking parameters
256 if (app_id == NULL) {
257 LogError("security_manager_app_get_pkgid: app_id is NULL");
258 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
261 if (pkg_id == NULL) {
262 LogError("security_manager_app_get_pkgid: pkg_id is NULL");
263 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
266 //put data into buffer
267 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
268 Serialization::Serialize(send, std::string(app_id));
270 //send buffer to server
271 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
272 if (retval != SECURITY_MANAGER_API_SUCCESS) {
273 LogDebug("Error in sendToServer. Error code: " << retval);
274 return SECURITY_MANAGER_ERROR_UNKNOWN;
277 //receive response from server
278 Deserialization::Deserialize(recv, retval);
279 if (retval != SECURITY_MANAGER_API_SUCCESS)
280 return SECURITY_MANAGER_ERROR_UNKNOWN;
282 std::string pkgIdString;
283 Deserialization::Deserialize(recv, pkgIdString);
284 if (pkgIdString.empty()) {
285 LogError("Unexpected empty pkgId");
286 return SECURITY_MANAGER_ERROR_UNKNOWN;
289 *pkg_id = strdup(pkgIdString.c_str());
290 if (*pkg_id == NULL) {
291 LogError("Failed to allocate memory for pkgId");
292 return SECURITY_MANAGER_ERROR_MEMORY;
295 return SECURITY_MANAGER_SUCCESS;
299 static bool setup_smack(const char *label)
301 int labelSize = strlen(label);
303 // Set Smack label for open socket file descriptors
305 std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
306 opendir("/proc/self/fd"), closedir);
308 LogError("Unable to read list of open file descriptors: " <<
310 return SECURITY_MANAGER_ERROR_UNKNOWN;
315 struct dirent *dirEntry = readdir(dir.get());
316 if (dirEntry == nullptr) {
317 if (errno == 0) // NULL return value also signals end of directory
320 LogError("Unable to read list of open file descriptors: " <<
322 return SECURITY_MANAGER_ERROR_UNKNOWN;
325 // Entries with numerical names specify file descriptors, ignore the rest
326 if (!isdigit(dirEntry->d_name[0]))
330 int fd = atoi(dirEntry->d_name);
331 int ret = fstat(fd, &statBuf);
333 LogWarning("fstat failed on file descriptor " << fd << ": " <<
337 if (S_ISSOCK(statBuf.st_mode)) {
338 ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
340 LogError("Setting Smack label failed on file descriptor " <<
341 fd << ": " << strerror(errno));
342 return SECURITY_MANAGER_ERROR_UNKNOWN;
345 ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
347 LogError("Setting Smack label failed on file descriptor " <<
348 fd << ": " << strerror(errno));
349 return SECURITY_MANAGER_ERROR_UNKNOWN;
354 // Set Smack label of current process
355 smack_set_label_for_self(label);
357 return SECURITY_MANAGER_SUCCESS;
361 int security_manager_set_process_label_from_appid(const char *app_id)
364 std::string appLabel;
366 LogDebug("security_manager_set_process_label_from_appid() called");
368 if (smack_smackfs_path() == NULL)
369 return SECURITY_MANAGER_SUCCESS;
371 // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
374 if (!getZoneIdFromPid(getpid(), zoneId)) {
375 LogError("Failed to get ID of zone");
376 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
380 appLabel = SecurityManager::zoneSmackLabelGenerate(
381 SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
384 LogError("Failed to generate smack label for appId: " << app_id);
385 return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
388 if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
389 LogError("Failed to set smack label " << appLabel << " for current process");
393 return SECURITY_MANAGER_SUCCESS;
397 int security_manager_set_process_groups_from_appid(const char *app_id)
399 using namespace SecurityManager;
400 MessageBuffer send, recv;
403 LogDebug("security_manager_set_process_groups_from_appid() called");
405 return try_catch([&] {
406 //checking parameters
408 if (app_id == nullptr) {
409 LogError("app_id is NULL");
410 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
413 //put data into buffer
414 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
415 Serialization::Serialize(send, std::string(app_id));
417 //send buffer to server
418 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
419 if (retval != SECURITY_MANAGER_API_SUCCESS) {
420 LogDebug("Error in sendToServer. Error code: " << retval);
421 return SECURITY_MANAGER_ERROR_UNKNOWN;
424 //receive response from server
425 Deserialization::Deserialize(recv, retval);
426 if (retval != SECURITY_MANAGER_API_SUCCESS) {
427 LogError("Failed to get list of groups from security-manager service. Error code: " << retval);
428 return SECURITY_MANAGER_ERROR_UNKNOWN;
431 //How many new groups?
433 Deserialization::Deserialize(recv, newGroupsCnt);
435 //And how many groups do we belong to already?
437 ret = getgroups(0, nullptr);
439 LogError("Unable to get list of current supplementary groups: " <<
441 return SECURITY_MANAGER_ERROR_UNKNOWN;
445 //Allocate an array for both old and new groups gids
446 std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
448 LogError("Memory allocation failed.");
449 return SECURITY_MANAGER_ERROR_MEMORY;
452 //Get the old groups from process
453 ret = getgroups(oldGroupsCnt, groups.get());
455 LogError("Unable to get list of current supplementary groups: " <<
457 return SECURITY_MANAGER_ERROR_UNKNOWN;
460 //Get the new groups from server response
461 for (int i = 0; i < newGroupsCnt; ++i) {
463 Deserialization::Deserialize(recv, gid);
464 groups.get()[oldGroupsCnt + i] = gid;
465 LogDebug("Adding process to group " << gid);
468 //Apply the modified groups list
469 ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
471 LogError("Unable to get list of current supplementary groups: " <<
473 return SECURITY_MANAGER_ERROR_UNKNOWN;
476 return SECURITY_MANAGER_SUCCESS;
481 int security_manager_drop_process_privileges(void)
483 LogDebug("security_manager_drop_process_privileges() called");
486 cap_t cap = cap_init();
488 LogError("Unable to allocate capability object");
489 return SECURITY_MANAGER_ERROR_MEMORY;
492 ret = cap_clear(cap);
494 LogError("Unable to initialize capability object");
496 return SECURITY_MANAGER_ERROR_UNKNOWN;
499 ret = cap_set_proc(cap);
501 LogError("Unable to drop process capabilities");
503 return SECURITY_MANAGER_ERROR_UNKNOWN;
507 return SECURITY_MANAGER_SUCCESS;
511 int security_manager_prepare_app(const char *app_id)
513 LogDebug("security_manager_prepare_app() called");
516 ret = security_manager_set_process_label_from_appid(app_id);
517 if (ret != SECURITY_MANAGER_SUCCESS)
520 ret = security_manager_set_process_groups_from_appid(app_id);
521 if (ret != SECURITY_MANAGER_SUCCESS) {
522 LogWarning("Unable to setup process groups for application. Privileges with direct access to resources will not work.");
523 ret = SECURITY_MANAGER_SUCCESS;
526 ret = security_manager_drop_process_privileges();
531 int security_manager_user_req_new(user_req **pp_req)
534 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
536 *pp_req = new user_req;
537 } catch (std::bad_alloc& ex) {
538 return SECURITY_MANAGER_ERROR_MEMORY;
540 return SECURITY_MANAGER_SUCCESS;
544 void security_manager_user_req_free(user_req *p_req)
550 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
553 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
557 return SECURITY_MANAGER_SUCCESS;
561 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
564 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
566 p_req->utype = static_cast<int>(utype);
568 return SECURITY_MANAGER_SUCCESS;
572 int security_manager_user_add(const user_req *p_req)
574 using namespace SecurityManager;
576 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
578 return try_catch([&] {
580 ClientOffline offlineMode;
581 if (offlineMode.isOffline()) {
582 retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid(),
585 MessageBuffer send, recv;
588 //put data into buffer
589 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD));
591 Serialization::Serialize(send, p_req->uid);
592 Serialization::Serialize(send, p_req->utype);
594 //send buffer to server
595 retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
596 if (retval != SECURITY_MANAGER_API_SUCCESS) {
597 LogError("Error in sendToServer. Error code: " << retval);
598 return SECURITY_MANAGER_ERROR_UNKNOWN;
601 //receive response from server
602 Deserialization::Deserialize(recv, retval);
605 case SECURITY_MANAGER_API_SUCCESS:
606 return SECURITY_MANAGER_SUCCESS;
607 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
608 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
610 return SECURITY_MANAGER_ERROR_UNKNOWN;
616 int security_manager_user_delete(const user_req *p_req)
618 using namespace SecurityManager;
619 MessageBuffer send, recv;
621 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
622 return try_catch([&] {
624 //put data into buffer
625 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE));
627 Serialization::Serialize(send, p_req->uid);
630 //send buffer to server
631 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
632 if (retval != SECURITY_MANAGER_API_SUCCESS) {
633 LogError("Error in sendToServer. Error code: " << retval);
634 return SECURITY_MANAGER_ERROR_UNKNOWN;
637 //receive response from server
638 Deserialization::Deserialize(recv, retval);
640 case SECURITY_MANAGER_API_SUCCESS:
641 return SECURITY_MANAGER_SUCCESS;
642 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
643 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
645 return SECURITY_MANAGER_ERROR_UNKNOWN;
651 /***************************POLICY***************************************/
654 int security_manager_policy_update_req_new(policy_update_req **pp_req)
657 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
660 *pp_req = new policy_update_req;
661 } catch (std::bad_alloc& ex) {
662 return SECURITY_MANAGER_ERROR_MEMORY;
665 return SECURITY_MANAGER_SUCCESS;
669 void security_manager_policy_update_req_free(policy_update_req *p_req)
675 int security_manager_policy_update_send(policy_update_req *p_req)
677 using namespace SecurityManager;
678 MessageBuffer send, recv;
680 if (p_req == nullptr || p_req->units.size() == 0)
681 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
683 return try_catch([&] {
685 //put request into buffer
686 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
687 Serialization::Serialize(send, p_req->units);
690 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
691 if (retval != SECURITY_MANAGER_API_SUCCESS) {
692 LogError("Error in sendToServer. Error code: " << retval);
693 return SECURITY_MANAGER_ERROR_UNKNOWN;
696 //receive response from server
697 Deserialization::Deserialize(recv, retval);
699 case SECURITY_MANAGER_API_SUCCESS:
700 return SECURITY_MANAGER_SUCCESS;
701 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
702 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
703 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
704 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
706 return SECURITY_MANAGER_ERROR_UNKNOWN;
711 static inline int security_manager_get_policy_internal(
712 SecurityManager::SecurityModuleCall call_type,
713 policy_entry *p_filter,
714 policy_entry ***ppp_privs_policy,
717 using namespace SecurityManager;
718 MessageBuffer send, recv;
720 if (ppp_privs_policy == nullptr
722 || p_filter == nullptr)
723 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
725 return try_catch([&] {
726 //put request into buffer
727 Serialization::Serialize(send, static_cast<int>(call_type));
728 Serialization::Serialize(send, *p_filter);
730 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
731 if (retval != SECURITY_MANAGER_API_SUCCESS) {
732 LogError("Error in sendToServer. Error code: " << retval);
733 return SECURITY_MANAGER_ERROR_UNKNOWN;
735 //receive response from server
736 Deserialization::Deserialize(recv, retval);
738 case SECURITY_MANAGER_API_SUCCESS: {
739 //extract and allocate buffers for privs policy entries
741 policy_entry **entries = nullptr;
743 Deserialization::Deserialize(recv, entriesCnt);
744 entries = new policy_entry*[entriesCnt]();
745 for (int i = 0; i < entriesCnt; ++i) {
746 entries[i] = new policy_entry;
747 Deserialization::Deserialize(recv, entries[i]);
750 LogError("Error while parsing server response");
751 for (int i = 0; i < entriesCnt; ++i)
754 return SECURITY_MANAGER_ERROR_UNKNOWN;
756 *p_size = entriesCnt;
757 *ppp_privs_policy = entries;
758 return SECURITY_MANAGER_SUCCESS;
760 case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
761 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
763 case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
764 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
767 return SECURITY_MANAGER_ERROR_UNKNOWN;
773 int security_manager_get_configured_policy_for_admin(
774 policy_entry *p_filter,
775 policy_entry ***ppp_privs_policy,
778 return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
782 int security_manager_get_configured_policy_for_self(
783 policy_entry *p_filter,
784 policy_entry ***ppp_privs_policy,
787 return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
791 int security_manager_get_policy(
792 policy_entry *p_filter,
793 policy_entry ***ppp_privs_policy,
796 return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
800 int security_manager_policy_entry_new(policy_entry **p_entry)
803 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
806 *p_entry = new policy_entry;
807 } catch (std::bad_alloc& ex) {
808 return SECURITY_MANAGER_ERROR_MEMORY;
811 return SECURITY_MANAGER_SUCCESS;
815 void security_manager_policy_entry_free(policy_entry *p_entry)
821 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
824 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
825 p_entry->appId = app_id;
826 return SECURITY_MANAGER_SUCCESS;
830 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
833 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
834 p_entry->user = user;
835 return SECURITY_MANAGER_SUCCESS;
839 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
842 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
843 p_entry->privilege = privilege;
844 return SECURITY_MANAGER_SUCCESS;
848 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
851 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
852 p_entry->currentLevel = policy_level;
853 p_entry->maxLevel = EMPTY;
854 return SECURITY_MANAGER_SUCCESS;
858 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
861 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
862 p_entry->maxLevel = policy_level;
863 p_entry->currentLevel = EMPTY;
864 return SECURITY_MANAGER_SUCCESS;
868 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
870 if (!p_entry || !p_req)
871 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
872 p_req->units.push_back(p_entry);
874 return SECURITY_MANAGER_SUCCESS;
878 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
880 return p_entry ? p_entry->user.c_str() : nullptr;
884 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
886 return p_entry ? p_entry->appId.c_str() : nullptr;
889 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
891 return p_entry ? p_entry->privilege.c_str() : nullptr;
894 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
896 return p_entry ? p_entry->currentLevel.c_str() : nullptr;
900 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
902 return p_entry ? p_entry->maxLevel.c_str() : nullptr;
906 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
908 for (size_t i = 0; i < size; i++) {
909 delete &p_entries[i];
915 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
917 using namespace SecurityManager;
918 MessageBuffer send, recv;
919 if (!levels || !levels_count)
920 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
921 return try_catch([&] {
923 //put data into buffer
924 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
926 //send buffer to server
927 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
928 if (retval != SECURITY_MANAGER_API_SUCCESS) {
929 LogError("Error in sendToServer. Error code: " << retval);
930 return SECURITY_MANAGER_ERROR_UNKNOWN;
933 //receive response from server
934 Deserialization::Deserialize(recv, retval);
937 case SECURITY_MANAGER_API_SUCCESS:
938 // success - continue
940 case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
941 return SECURITY_MANAGER_ERROR_MEMORY;
942 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
943 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
945 return SECURITY_MANAGER_ERROR_UNKNOWN;
949 Deserialization::Deserialize(recv, count);
950 *levels_count = count;
951 LogInfo("Number of policy descriptions: " << *levels_count);
953 char **array = new char *[*levels_count];
955 for (unsigned int i = 0; i < *levels_count; ++i) {
957 Deserialization::Deserialize(recv, level);
960 LogError("Unexpected empty level");
961 return SECURITY_MANAGER_ERROR_UNKNOWN;
964 array[i] = strdup(level.c_str());
965 if (array[i] == nullptr)
966 return SECURITY_MANAGER_ERROR_MEMORY;
971 return SECURITY_MANAGER_SUCCESS;
976 void security_manager_policy_levels_free(char **levels, size_t levels_count)
978 for (unsigned int i = 0; i < levels_count; i++)
984 lib_retcode get_privileges_mapping(const std::string &from_version,
985 const std::string &to_version,
986 const std::vector<std::string> &privileges,
987 char ***privileges_mappings,
988 size_t *mappings_count)
990 using namespace SecurityManager;
991 MessageBuffer send, recv;
992 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GET_PRIVILEGES_MAPPING));
993 Serialization::Serialize(send, from_version);
994 Serialization::Serialize(send, to_version);
995 Serialization::Serialize(send, privileges);
997 //send buffer to server
998 int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
999 if (retval != SECURITY_MANAGER_API_SUCCESS) {
1000 LogError("Error in sendToServer. Error code: " << retval);
1001 return SECURITY_MANAGER_ERROR_UNKNOWN;
1004 //receive response from server
1005 Deserialization::Deserialize(recv, retval);
1008 case SECURITY_MANAGER_API_SUCCESS:
1009 // success - continue
1011 case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1012 return SECURITY_MANAGER_ERROR_MEMORY;
1013 case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1014 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1016 return SECURITY_MANAGER_ERROR_UNKNOWN;
1020 Deserialization::Deserialize(recv, count);
1021 LogInfo("Number of privilege mappings: " << count);
1023 auto free_mapping = std::bind(security_manager_privilege_mapping_free,
1024 std::placeholders::_1, std::ref(i));
1025 std::unique_ptr<char *[], decltype (free_mapping)> mappings_ptr(new char *[count], free_mapping);
1027 for (; i < count; ++i) {
1028 std::string privilege_mapping;
1029 Deserialization::Deserialize(recv, privilege_mapping);
1030 if (privilege_mapping.empty()) {
1031 LogError("Unexpected empty privilege mapping");
1032 return SECURITY_MANAGER_ERROR_UNKNOWN;
1035 mappings_ptr.get()[i] = strdup(privilege_mapping.c_str());
1036 if (mappings_ptr.get()[i] == nullptr)
1037 return SECURITY_MANAGER_ERROR_MEMORY;
1040 *privileges_mappings = mappings_ptr.release();
1041 *mappings_count = count;
1043 return SECURITY_MANAGER_SUCCESS;
1046 SECURITY_MANAGER_API
1047 int security_manager_get_privileges_mapping(const char *from_version,
1048 const char *to_version,
1049 char const * const *privileges,
1050 size_t privileges_count,
1051 char ***privileges_mappings,
1052 size_t *mappings_count)
1054 if (from_version == nullptr || privileges_mappings == nullptr || mappings_count == nullptr) {
1055 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1057 return try_catch([&] {
1058 std::vector<std::string> privilegesToMap;
1059 if (privileges != nullptr) {
1060 privilegesToMap.reserve(privileges_count);
1061 privilegesToMap.insert(privilegesToMap.end(), privileges, privileges + privileges_count);
1063 if (to_version == nullptr)
1065 LogDebug("security_manager_get_privileges_mapping() called with :"
1066 " from_version = " << from_version << " to_version = " << to_version <<
1067 " privileges_count " << privilegesToMap.size());
1069 return get_privileges_mapping(from_version, to_version, privilegesToMap,
1070 privileges_mappings, mappings_count);
1074 SECURITY_MANAGER_API
1075 void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
1077 for(size_t i = 0; i < mappings_count; i++)
1078 free(privileges_mappings[i]);
1079 delete [] privileges_mappings;