Add API for privilege mapping between versions
[platform/core/security/security-manager.git] / src / client / client-security-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Rafal Krypa <r.krypa@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  *
18  *      Security Manager library header
19  */
20 /*
21  * @file        client-security-manager.cpp
22  * @author      Pawel Polawski <p.polawski@samsung.com>
23  * @author      Rafal Krypa <r.krypa@samsung.com>
24  * @version     1.0
25  * @brief       This file contain client side implementation of security-manager API
26  */
27
28 #include <cstdio>
29 #include <utility>
30
31 #include <unistd.h>
32 #include <grp.h>
33 #include <dirent.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/xattr.h>
37 #include <sys/smack.h>
38 #include <sys/capability.h>
39
40 #include <dpl/log/log.h>
41 #include <dpl/exception.h>
42 #include <smack-labels.h>
43 #include <message-buffer.h>
44 #include <client-common.h>
45 #include <protocols.h>
46 #include <service_impl.h>
47 #include <connection.h>
48 #include <zone-utils.h>
49
50 #include <security-manager.h>
51 #include <client-offline.h>
52
53 static const char *EMPTY = "";
54
55 /**
56  * Mapping of lib_retcode error codes to theirs strings equivalents
57  */
58 static std::map<enum lib_retcode, std::string> lib_retcode_string_map = {
59     {SECURITY_MANAGER_SUCCESS, "Success"},
60     {SECURITY_MANAGER_ERROR_UNKNOWN, "Unknown error"},
61     {SECURITY_MANAGER_ERROR_INPUT_PARAM, "Invalid function parameter was given"},
62     {SECURITY_MANAGER_ERROR_MEMORY, "Memory allocation error"},
63     {SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, "Incomplete data in application request"},
64     {SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "User does not have sufficient "
65                                                    "rigths to perform an operation"},
66     {SECURITY_MANAGER_ERROR_ACCESS_DENIED, "Insufficient privileges"},
67 };
68
69 SECURITY_MANAGER_API
70 const char *security_manager_strerror(enum lib_retcode rc)
71 {
72     try {
73         return lib_retcode_string_map.at(rc).c_str();
74     } catch (const std::out_of_range &e) {
75         return "Unknown error code";
76     }
77 }
78
79 SECURITY_MANAGER_API
80 int security_manager_app_inst_req_new(app_inst_req **pp_req)
81 {
82     if (!pp_req)
83         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
84
85     try {
86         *pp_req = new app_inst_req;
87     } catch (std::bad_alloc& ex) {
88         return SECURITY_MANAGER_ERROR_MEMORY;
89     }
90     (*pp_req)->uid = geteuid();
91
92     return SECURITY_MANAGER_SUCCESS;
93 }
94
95 SECURITY_MANAGER_API
96 void security_manager_app_inst_req_free(app_inst_req *p_req)
97 {
98     delete p_req;
99 }
100
101 SECURITY_MANAGER_API
102 int security_manager_app_inst_req_set_uid(app_inst_req *p_req,
103                                           const uid_t uid)
104 {
105     if (!p_req)
106         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
107
108     p_req->uid = uid;
109
110     return SECURITY_MANAGER_SUCCESS;
111 }
112
113 SECURITY_MANAGER_API
114 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
115 {
116     if (!p_req || !app_id)
117         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
118
119     p_req->appId = app_id;
120
121     return SECURITY_MANAGER_SUCCESS;
122 }
123
124 SECURITY_MANAGER_API
125 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
126 {
127     if (!p_req || !pkg_id)
128         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
129
130     p_req->pkgId = pkg_id;
131
132     return SECURITY_MANAGER_SUCCESS;
133 }
134
135 SECURITY_MANAGER_API
136 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
137 {
138     if (!p_req || !privilege)
139         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
140
141     p_req->privileges.push_back(privilege);
142
143     return SECURITY_MANAGER_SUCCESS;
144 }
145
146 SECURITY_MANAGER_API
147 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
148 {
149     if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
150         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
151
152     p_req->appPaths.push_back(std::make_pair(path, path_type));
153
154     return SECURITY_MANAGER_SUCCESS;
155 }
156
157 SECURITY_MANAGER_API
158 int security_manager_app_install(const app_inst_req *p_req)
159 {
160     using namespace SecurityManager;
161
162     return try_catch([&] {
163         //checking parameters
164         if (!p_req)
165             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
166         if (p_req->appId.empty() || p_req->pkgId.empty())
167             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
168
169         int retval;
170         ClientOffline offlineMode;
171         if (offlineMode.isOffline()) {
172             retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid(), false);
173         } else {
174             MessageBuffer send, recv;
175
176             //put data into buffer
177             Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL);
178             Serialization::Serialize(send, p_req->appId);
179             Serialization::Serialize(send, p_req->pkgId);
180             Serialization::Serialize(send, p_req->privileges);
181             Serialization::Serialize(send, p_req->appPaths);
182             Serialization::Serialize(send, p_req->uid);
183
184             //send buffer to server
185             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
186             if (retval != SECURITY_MANAGER_API_SUCCESS) {
187                 LogError("Error in sendToServer. Error code: " << retval);
188                 return SECURITY_MANAGER_ERROR_UNKNOWN;
189             }
190
191             //receive response from server
192             Deserialization::Deserialize(recv, retval);
193         }
194         switch(retval) {
195             case SECURITY_MANAGER_API_SUCCESS:
196                 return SECURITY_MANAGER_SUCCESS;
197             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
198                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
199             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
200                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
201             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
202                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
203             default:
204                 return SECURITY_MANAGER_ERROR_UNKNOWN;
205         }
206
207     });
208 }
209
210 SECURITY_MANAGER_API
211 int security_manager_app_uninstall(const app_inst_req *p_req)
212 {
213     using namespace SecurityManager;
214     MessageBuffer send, recv;
215
216     return try_catch([&] {
217         //checking parameters
218         if (!p_req)
219             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
220         if (p_req->appId.empty())
221             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
222
223         //put data into buffer
224         Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
225         Serialization::Serialize(send, p_req->appId);
226
227         //send buffer to server
228         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
229         if (retval != SECURITY_MANAGER_API_SUCCESS) {
230             LogError("Error in sendToServer. Error code: " << retval);
231             return SECURITY_MANAGER_ERROR_UNKNOWN;
232         }
233
234         //receive response from server
235         Deserialization::Deserialize(recv, retval);
236         if (retval != SECURITY_MANAGER_API_SUCCESS)
237             return SECURITY_MANAGER_ERROR_UNKNOWN;
238
239         return SECURITY_MANAGER_SUCCESS;;
240     });
241 }
242
243 SECURITY_MANAGER_API
244 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
245 {
246     using namespace SecurityManager;
247     MessageBuffer send, recv;
248
249     LogDebug("security_manager_get_app_pkgid() called");
250
251     return try_catch([&] {
252         //checking parameters
253
254         if (app_id == NULL) {
255             LogError("security_manager_app_get_pkgid: app_id is NULL");
256             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
257         }
258
259         if (pkg_id == NULL) {
260             LogError("security_manager_app_get_pkgid: pkg_id is NULL");
261             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
262         }
263
264         //put data into buffer
265         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
266         Serialization::Serialize(send, std::string(app_id));
267
268         //send buffer to server
269         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
270         if (retval != SECURITY_MANAGER_API_SUCCESS) {
271             LogDebug("Error in sendToServer. Error code: " << retval);
272             return SECURITY_MANAGER_ERROR_UNKNOWN;
273         }
274
275         //receive response from server
276         Deserialization::Deserialize(recv, retval);
277         if (retval != SECURITY_MANAGER_API_SUCCESS)
278             return SECURITY_MANAGER_ERROR_UNKNOWN;
279
280         std::string pkgIdString;
281         Deserialization::Deserialize(recv, pkgIdString);
282         if (pkgIdString.empty()) {
283             LogError("Unexpected empty pkgId");
284             return SECURITY_MANAGER_ERROR_UNKNOWN;
285         }
286
287         *pkg_id = strdup(pkgIdString.c_str());
288         if (*pkg_id == NULL) {
289             LogError("Failed to allocate memory for pkgId");
290             return SECURITY_MANAGER_ERROR_MEMORY;
291         }
292
293         return SECURITY_MANAGER_SUCCESS;
294     });
295 }
296
297 static bool setup_smack(const char *label)
298 {
299     int labelSize = strlen(label);
300
301     // Set Smack label for open socket file descriptors
302
303     std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
304         opendir("/proc/self/fd"), closedir);
305     if (!dir.get()) {
306         LogError("Unable to read list of open file descriptors: " <<
307             strerror(errno));
308         return SECURITY_MANAGER_ERROR_UNKNOWN;
309     }
310
311     do {
312         errno = 0;
313         struct dirent *dirEntry = readdir(dir.get());
314         if (dirEntry == nullptr) {
315             if (errno == 0) // NULL return value also signals end of directory
316                 break;
317
318             LogError("Unable to read list of open file descriptors: " <<
319                 strerror(errno));
320             return SECURITY_MANAGER_ERROR_UNKNOWN;
321         }
322
323         // Entries with numerical names specify file descriptors, ignore the rest
324         if (!isdigit(dirEntry->d_name[0]))
325             continue;
326
327         struct stat statBuf;
328         int fd = atoi(dirEntry->d_name);
329         int ret = fstat(fd, &statBuf);
330         if (ret != 0) {
331             LogWarning("fstat failed on file descriptor " << fd << ": " <<
332                 strerror(errno));
333             continue;
334         }
335         if (S_ISSOCK(statBuf.st_mode)) {
336             ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
337             if (ret != 0) {
338                 LogError("Setting Smack label failed on file descriptor " <<
339                     fd << ": " << strerror(errno));
340                 return SECURITY_MANAGER_ERROR_UNKNOWN;
341             }
342
343             ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
344             if (ret != 0) {
345                 LogError("Setting Smack label failed on file descriptor " <<
346                     fd << ": " << strerror(errno));
347                 return SECURITY_MANAGER_ERROR_UNKNOWN;
348             }
349         }
350     } while (true);
351
352     // Set Smack label of current process
353     smack_set_label_for_self(label);
354
355     return SECURITY_MANAGER_SUCCESS;
356 }
357
358 SECURITY_MANAGER_API
359 int security_manager_set_process_label_from_appid(const char *app_id)
360 {
361     int ret;
362     std::string appLabel;
363
364     LogDebug("security_manager_set_process_label_from_appid() called");
365
366     if (smack_smackfs_path() == NULL)
367         return SECURITY_MANAGER_SUCCESS;
368
369     // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
370     //       are implemented.
371     std::string zoneId;
372     if (!getZoneIdFromPid(getpid(), zoneId)) {
373         LogError("Failed to get ID of zone");
374         return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
375     }
376
377     try {
378         appLabel = SecurityManager::zoneSmackLabelGenerate(
379                 SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
380
381     } catch (...) {
382         LogError("Failed to generate smack label for appId: " << app_id);
383         return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
384     }
385
386     if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
387         LogError("Failed to set smack label " << appLabel << " for current process");
388         return ret;
389     }
390
391     return SECURITY_MANAGER_SUCCESS;
392 }
393
394 SECURITY_MANAGER_API
395 int security_manager_set_process_groups_from_appid(const char *app_id)
396 {
397     using namespace SecurityManager;
398     MessageBuffer send, recv;
399     int ret;
400
401     LogDebug("security_manager_set_process_groups_from_appid() called");
402
403     return try_catch([&] {
404         //checking parameters
405
406         if (app_id == nullptr) {
407             LogError("app_id is NULL");
408             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
409         }
410
411         //put data into buffer
412         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
413         Serialization::Serialize(send, std::string(app_id));
414
415         //send buffer to server
416         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
417         if (retval != SECURITY_MANAGER_API_SUCCESS) {
418             LogDebug("Error in sendToServer. Error code: " << retval);
419             return SECURITY_MANAGER_ERROR_UNKNOWN;
420         }
421
422         //receive response from server
423         Deserialization::Deserialize(recv, retval);
424         if (retval != SECURITY_MANAGER_API_SUCCESS) {
425             LogError("Failed to get list of groups from security-manager service. Error code: " << retval);
426             return SECURITY_MANAGER_ERROR_UNKNOWN;
427         }
428
429         //How many new groups?
430         int newGroupsCnt;
431         Deserialization::Deserialize(recv, newGroupsCnt);
432
433         //And how many groups do we belong to already?
434         int oldGroupsCnt;
435         ret = getgroups(0, nullptr);
436         if (ret == -1) {
437             LogError("Unable to get list of current supplementary groups: " <<
438                 strerror(errno));
439             return SECURITY_MANAGER_ERROR_UNKNOWN;
440         }
441         oldGroupsCnt = ret;
442
443         //Allocate an array for both old and new groups gids
444         std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
445         if (!groups.get()) {
446             LogError("Memory allocation failed.");
447             return SECURITY_MANAGER_ERROR_MEMORY;
448         }
449
450         //Get the old groups from process
451         ret = getgroups(oldGroupsCnt, groups.get());
452         if (ret == -1) {
453             LogError("Unable to get list of current supplementary groups: " <<
454                 strerror(errno));
455             return SECURITY_MANAGER_ERROR_UNKNOWN;
456         }
457
458         //Get the new groups from server response
459         for (int i = 0; i < newGroupsCnt; ++i) {
460             gid_t gid;
461             Deserialization::Deserialize(recv, gid);
462             groups.get()[oldGroupsCnt + i] = gid;
463             LogDebug("Adding process to group " << gid);
464         }
465
466         //Apply the modified groups list
467         ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
468         if (ret == -1) {
469             LogError("Unable to get list of current supplementary groups: " <<
470                 strerror(errno));
471             return SECURITY_MANAGER_ERROR_UNKNOWN;
472         }
473
474         return SECURITY_MANAGER_SUCCESS;
475     });
476 }
477
478 SECURITY_MANAGER_API
479 int security_manager_drop_process_privileges(void)
480 {
481     LogDebug("security_manager_drop_process_privileges() called");
482
483     int ret;
484     cap_t cap = cap_init();
485     if (!cap) {
486         LogError("Unable to allocate capability object");
487         return SECURITY_MANAGER_ERROR_MEMORY;
488     }
489
490     ret = cap_clear(cap);
491     if (ret) {
492         LogError("Unable to initialize capability object");
493         cap_free(cap);
494         return SECURITY_MANAGER_ERROR_UNKNOWN;
495     }
496
497     ret = cap_set_proc(cap);
498     if (ret) {
499         LogError("Unable to drop process capabilities");
500         cap_free(cap);
501         return SECURITY_MANAGER_ERROR_UNKNOWN;
502     }
503
504     cap_free(cap);
505     return SECURITY_MANAGER_SUCCESS;
506 }
507
508 SECURITY_MANAGER_API
509 int security_manager_prepare_app(const char *app_id)
510 {
511     LogDebug("security_manager_prepare_app() called");
512     int ret;
513
514     ret = security_manager_set_process_label_from_appid(app_id);
515     if (ret != SECURITY_MANAGER_SUCCESS)
516         return ret;
517
518     ret = security_manager_set_process_groups_from_appid(app_id);
519     if (ret != SECURITY_MANAGER_SUCCESS) {
520         LogWarning("Unable to setup process groups for application. Privileges with direct access to resources will not work.");
521         ret = SECURITY_MANAGER_SUCCESS;
522     }
523
524     ret = security_manager_drop_process_privileges();
525     return ret;
526 }
527
528 SECURITY_MANAGER_API
529 int security_manager_user_req_new(user_req **pp_req)
530 {
531     if (!pp_req)
532         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
533     try {
534         *pp_req = new user_req;
535     } catch (std::bad_alloc& ex) {
536         return SECURITY_MANAGER_ERROR_MEMORY;
537     }
538     return SECURITY_MANAGER_SUCCESS;
539 }
540
541 SECURITY_MANAGER_API
542 void security_manager_user_req_free(user_req *p_req)
543 {
544     delete p_req;
545 }
546
547 SECURITY_MANAGER_API
548 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
549 {
550     if (!p_req)
551         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
552
553     p_req->uid = uid;
554
555     return SECURITY_MANAGER_SUCCESS;
556 }
557
558 SECURITY_MANAGER_API
559 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
560 {
561     if (!p_req)
562         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
563
564     p_req->utype = static_cast<int>(utype);
565
566     return SECURITY_MANAGER_SUCCESS;
567 }
568
569 SECURITY_MANAGER_API
570 int security_manager_user_add(const user_req *p_req)
571 {
572     using namespace SecurityManager;
573     if (!p_req)
574         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
575
576     return try_catch([&] {
577         int retval;
578         ClientOffline offlineMode;
579         if (offlineMode.isOffline()) {
580             retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid(),
581                                                            false);
582         } else {
583             MessageBuffer send, recv;
584             //server is working
585
586             //put data into buffer
587             Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD));
588
589             Serialization::Serialize(send, p_req->uid);
590             Serialization::Serialize(send, p_req->utype);
591
592             //send buffer to server
593             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
594             if (retval != SECURITY_MANAGER_API_SUCCESS) {
595                 LogError("Error in sendToServer. Error code: " << retval);
596                 return SECURITY_MANAGER_ERROR_UNKNOWN;
597             }
598
599             //receive response from server
600             Deserialization::Deserialize(recv, retval);
601         }
602         switch(retval) {
603         case SECURITY_MANAGER_API_SUCCESS:
604             return SECURITY_MANAGER_SUCCESS;
605         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
606             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
607         default:
608             return SECURITY_MANAGER_ERROR_UNKNOWN;
609         }
610     });
611 }
612
613 SECURITY_MANAGER_API
614 int security_manager_user_delete(const user_req *p_req)
615 {
616     using namespace SecurityManager;
617     MessageBuffer send, recv;
618     if (!p_req)
619         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
620     return try_catch([&] {
621
622         //put data into buffer
623         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE));
624
625         Serialization::Serialize(send, p_req->uid);
626
627
628         //send buffer to server
629         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
630         if (retval != SECURITY_MANAGER_API_SUCCESS) {
631             LogError("Error in sendToServer. Error code: " << retval);
632             return SECURITY_MANAGER_ERROR_UNKNOWN;
633         }
634
635         //receive response from server
636         Deserialization::Deserialize(recv, retval);
637         switch(retval) {
638         case SECURITY_MANAGER_API_SUCCESS:
639             return SECURITY_MANAGER_SUCCESS;
640         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
641             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
642         default:
643             return SECURITY_MANAGER_ERROR_UNKNOWN;
644         }
645     });
646 }
647
648
649 /***************************POLICY***************************************/
650
651 SECURITY_MANAGER_API
652 int security_manager_policy_update_req_new(policy_update_req **pp_req)
653 {
654     if (!pp_req)
655         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
656
657     try {
658         *pp_req = new policy_update_req;
659     } catch (std::bad_alloc& ex) {
660         return SECURITY_MANAGER_ERROR_MEMORY;
661     }
662
663     return SECURITY_MANAGER_SUCCESS;
664 }
665
666 SECURITY_MANAGER_API
667 void security_manager_policy_update_req_free(policy_update_req *p_req)
668 {
669     delete p_req;
670 }
671
672 SECURITY_MANAGER_API
673 int security_manager_policy_update_send(policy_update_req *p_req)
674 {
675     using namespace SecurityManager;
676     MessageBuffer send, recv;
677
678     if (p_req == nullptr || p_req->units.size() == 0)
679         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
680
681     return try_catch([&] {
682
683         //put request into buffer
684         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
685         Serialization::Serialize(send, p_req->units);
686
687         //send it to server
688         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
689         if (retval != SECURITY_MANAGER_API_SUCCESS) {
690             LogError("Error in sendToServer. Error code: " << retval);
691             return SECURITY_MANAGER_ERROR_UNKNOWN;
692         }
693
694         //receive response from server
695         Deserialization::Deserialize(recv, retval);
696         switch(retval) {
697             case SECURITY_MANAGER_API_SUCCESS:
698                 return SECURITY_MANAGER_SUCCESS;
699             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
700                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
701             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
702                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
703             default:
704                 return SECURITY_MANAGER_ERROR_UNKNOWN;
705         }
706     });
707 }
708
709 static inline int security_manager_get_policy_internal(
710         SecurityManager::SecurityModuleCall call_type,
711         policy_entry *p_filter,
712         policy_entry ***ppp_privs_policy,
713         size_t *p_size)
714 {
715     using namespace SecurityManager;
716     MessageBuffer send, recv;
717
718     if (ppp_privs_policy == nullptr
719         || p_size == nullptr
720         || p_filter == nullptr)
721         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
722
723     return try_catch([&] {
724         //put request into buffer
725         Serialization::Serialize(send, static_cast<int>(call_type));
726         Serialization::Serialize(send, *p_filter);
727         //send it to server
728         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
729         if (retval != SECURITY_MANAGER_API_SUCCESS) {
730             LogError("Error in sendToServer. Error code: " << retval);
731             return SECURITY_MANAGER_ERROR_UNKNOWN;
732         }
733         //receive response from server
734         Deserialization::Deserialize(recv, retval);
735         switch (retval) {
736             case SECURITY_MANAGER_API_SUCCESS: {
737                 //extract and allocate buffers for privs policy entries
738                 int entriesCnt = 0;
739                 policy_entry **entries = nullptr;
740                 try {
741                     Deserialization::Deserialize(recv, entriesCnt);
742                     entries = new policy_entry*[entriesCnt]();
743                     for (int i = 0; i < entriesCnt; ++i) {
744                         entries[i] = new policy_entry;
745                         Deserialization::Deserialize(recv, entries[i]);
746                     };
747                 } catch (...) {
748                     LogError("Error while parsing server response");
749                     for (int i = 0; i < entriesCnt; ++i)
750                         delete(entries[i]);
751                     delete[] entries;
752                     return SECURITY_MANAGER_ERROR_UNKNOWN;
753                 }
754                 *p_size = entriesCnt;
755                 *ppp_privs_policy = entries;
756                 return SECURITY_MANAGER_SUCCESS;
757             }
758             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
759                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
760
761             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
762                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
763
764             default:
765                 return SECURITY_MANAGER_ERROR_UNKNOWN;
766         }
767     });
768 }
769
770 SECURITY_MANAGER_API
771 int security_manager_get_configured_policy_for_admin(
772         policy_entry *p_filter,
773         policy_entry ***ppp_privs_policy,
774         size_t *p_size)
775 {
776     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
777 }
778
779 SECURITY_MANAGER_API
780 int security_manager_get_configured_policy_for_self(
781         policy_entry *p_filter,
782         policy_entry ***ppp_privs_policy,
783         size_t *p_size)
784 {
785     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
786 }
787
788 SECURITY_MANAGER_API
789 int security_manager_get_policy(
790         policy_entry *p_filter,
791         policy_entry ***ppp_privs_policy,
792         size_t *p_size)
793 {
794     return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
795 };
796
797 SECURITY_MANAGER_API
798 int security_manager_policy_entry_new(policy_entry **p_entry)
799 {
800     if (!p_entry)
801         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
802
803     try {
804         *p_entry = new policy_entry;
805     } catch (std::bad_alloc& ex) {
806         return SECURITY_MANAGER_ERROR_MEMORY;
807     }
808
809     return SECURITY_MANAGER_SUCCESS;
810 }
811
812 SECURITY_MANAGER_API
813 void security_manager_policy_entry_free(policy_entry *p_entry)
814 {
815     delete p_entry;
816 }
817
818 SECURITY_MANAGER_API
819 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
820 {
821     if (!p_entry)
822         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
823     p_entry->appId = app_id;
824     return  SECURITY_MANAGER_SUCCESS;
825 }
826
827 SECURITY_MANAGER_API
828 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
829 {
830     if (!p_entry)
831         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
832     p_entry->user = user;
833     return  SECURITY_MANAGER_SUCCESS;
834 }
835
836 SECURITY_MANAGER_API
837 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
838 {
839     if (!p_entry)
840         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
841     p_entry->privilege = privilege;
842     return  SECURITY_MANAGER_SUCCESS;
843 }
844
845 SECURITY_MANAGER_API
846 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
847 {
848     if (!p_entry)
849         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
850     p_entry->currentLevel = policy_level;
851     p_entry->maxLevel = EMPTY;
852     return  SECURITY_MANAGER_SUCCESS;
853 }
854
855 SECURITY_MANAGER_API
856 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
857 {
858     if (!p_entry)
859         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
860     p_entry->maxLevel = policy_level;
861     p_entry->currentLevel = EMPTY;
862     return  SECURITY_MANAGER_SUCCESS;
863 }
864
865 SECURITY_MANAGER_API
866 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
867 {
868     if (!p_entry || !p_req)
869         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
870     p_req->units.push_back(p_entry);
871
872     return  SECURITY_MANAGER_SUCCESS;
873 }
874
875 SECURITY_MANAGER_API
876 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
877 {
878     return p_entry ? p_entry->user.c_str() : nullptr;
879 }
880
881 SECURITY_MANAGER_API
882 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
883 {
884     return p_entry ? p_entry->appId.c_str() : nullptr;
885 }
886 SECURITY_MANAGER_API
887 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
888 {
889     return p_entry ? p_entry->privilege.c_str() : nullptr;
890 }
891 SECURITY_MANAGER_API
892 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
893 {
894     return p_entry ? p_entry->currentLevel.c_str() : nullptr;
895 }
896
897 SECURITY_MANAGER_API
898 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
899 {
900     return p_entry ? p_entry->maxLevel.c_str() : nullptr;
901 }
902
903 SECURITY_MANAGER_API
904 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
905 {
906     for (size_t i = 0; i < size; i++) {
907         delete &p_entries[i];
908     }
909     delete [] p_entries;
910 }
911
912 SECURITY_MANAGER_API
913 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
914 {
915     using namespace SecurityManager;
916     MessageBuffer send, recv;
917     if (!levels || !levels_count)
918         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
919     return try_catch([&] {
920
921         //put data into buffer
922         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
923
924         //send buffer to server
925         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
926         if (retval != SECURITY_MANAGER_API_SUCCESS) {
927             LogError("Error in sendToServer. Error code: " << retval);
928             return SECURITY_MANAGER_ERROR_UNKNOWN;
929         }
930
931         //receive response from server
932         Deserialization::Deserialize(recv, retval);
933
934         switch(retval) {
935             case SECURITY_MANAGER_API_SUCCESS:
936                 // success - continue
937                 break;
938             case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
939                 return SECURITY_MANAGER_ERROR_MEMORY;
940             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
941                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
942             default:
943                 return SECURITY_MANAGER_ERROR_UNKNOWN;
944         }
945
946         int count;
947         Deserialization::Deserialize(recv, count);
948         *levels_count = count;
949         LogInfo("Number of policy descriptions: " << *levels_count);
950
951         char **array = new char *[*levels_count];
952
953         for (unsigned int i = 0; i < *levels_count; ++i) {
954             std::string level;
955             Deserialization::Deserialize(recv, level);
956
957             if (level.empty()) {
958                 LogError("Unexpected empty level");
959                 return SECURITY_MANAGER_ERROR_UNKNOWN;
960             }
961
962             array[i] = strdup(level.c_str());
963             if (array[i] == nullptr)
964                 return SECURITY_MANAGER_ERROR_MEMORY;
965         }
966
967         *levels = array;
968
969         return SECURITY_MANAGER_SUCCESS;
970     });
971 }
972
973 SECURITY_MANAGER_API
974 void security_manager_policy_levels_free(char **levels, size_t levels_count)
975 {
976     for (unsigned int i = 0; i < levels_count; i++)
977         free(levels[i]);
978
979     delete[] levels;
980 }
981
982 SECURITY_MANAGER_API
983 int security_manager_get_privileges_mapping(const char *from_version,
984                                              const char *to_version,
985                                              char const * const *privileges,
986                                              size_t privileges_count,
987                                              char ***privileges_mappings,
988                                              size_t *mappings_count)
989 {
990     (void)to_version;
991     if (from_version == nullptr || privileges == nullptr ||
992             privileges_mappings == nullptr || mappings_count == nullptr || privileges_count == 0) {
993         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
994     }
995     return SECURITY_MANAGER_ERROR_UNKNOWN;
996 }
997 SECURITY_MANAGER_API
998 void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
999 {
1000     (void)privileges_mappings;
1001     (void)mappings_count;
1002 }