Add security_manager_groups_get() API
[platform/core/security/security-manager.git] / src / client / client-security-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2015 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 <functional>
30 #include <memory>
31 #include <utility>
32
33 #include <unistd.h>
34 #include <grp.h>
35 #include <dirent.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/xattr.h>
39 #include <sys/smack.h>
40 #include <sys/capability.h>
41
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>
51
52 #include <security-manager.h>
53 #include <client-offline.h>
54
55 static const char *EMPTY = "";
56
57 /**
58  * Mapping of lib_retcode error codes to theirs strings equivalents
59  */
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"},
69 };
70
71 SECURITY_MANAGER_API
72 const char *security_manager_strerror(enum lib_retcode rc)
73 {
74     try {
75         return lib_retcode_string_map.at(rc).c_str();
76     } catch (const std::out_of_range &e) {
77         return "Unknown error code";
78     }
79 }
80
81 SECURITY_MANAGER_API
82 int security_manager_app_inst_req_new(app_inst_req **pp_req)
83 {
84     if (!pp_req)
85         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
86
87     try {
88         *pp_req = new app_inst_req;
89     } catch (std::bad_alloc& ex) {
90         return SECURITY_MANAGER_ERROR_MEMORY;
91     }
92     (*pp_req)->uid = geteuid();
93
94     return SECURITY_MANAGER_SUCCESS;
95 }
96
97 SECURITY_MANAGER_API
98 void security_manager_app_inst_req_free(app_inst_req *p_req)
99 {
100     delete p_req;
101 }
102
103 SECURITY_MANAGER_API
104 int security_manager_app_inst_req_set_uid(app_inst_req *p_req,
105                                           const uid_t uid)
106 {
107     if (!p_req)
108         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
109
110     p_req->uid = uid;
111
112     return SECURITY_MANAGER_SUCCESS;
113 }
114
115 SECURITY_MANAGER_API
116 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
117 {
118     if (!p_req || !app_id)
119         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
120
121     p_req->appId = app_id;
122
123     return SECURITY_MANAGER_SUCCESS;
124 }
125
126 SECURITY_MANAGER_API
127 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
128 {
129     if (!p_req || !pkg_id)
130         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
131
132     p_req->pkgId = pkg_id;
133
134     return SECURITY_MANAGER_SUCCESS;
135 }
136
137 SECURITY_MANAGER_API
138 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
139 {
140     if (!p_req || !privilege)
141         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
142
143     p_req->privileges.push_back(privilege);
144
145     return SECURITY_MANAGER_SUCCESS;
146 }
147
148 SECURITY_MANAGER_API
149 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
150 {
151     if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
152         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
153
154     p_req->appPaths.push_back(std::make_pair(path, path_type));
155
156     return SECURITY_MANAGER_SUCCESS;
157 }
158
159 SECURITY_MANAGER_API
160 int security_manager_app_install(const app_inst_req *p_req)
161 {
162     using namespace SecurityManager;
163
164     return try_catch([&] {
165         //checking parameters
166         if (!p_req)
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;
170
171         int retval;
172         ClientOffline offlineMode;
173         if (offlineMode.isOffline()) {
174             retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid(), false);
175         } else {
176             MessageBuffer send, recv;
177
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);
185
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;
191             }
192
193             //receive response from server
194             Deserialization::Deserialize(recv, retval);
195         }
196         switch(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;
205             default:
206                 return SECURITY_MANAGER_ERROR_UNKNOWN;
207         }
208
209     });
210 }
211
212 SECURITY_MANAGER_API
213 int security_manager_app_uninstall(const app_inst_req *p_req)
214 {
215     using namespace SecurityManager;
216     MessageBuffer send, recv;
217
218     return try_catch([&] {
219         //checking parameters
220         if (!p_req)
221             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
222         if (p_req->appId.empty())
223             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
224
225         //put data into buffer
226         Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
227         Serialization::Serialize(send, p_req->appId);
228
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;
234         }
235
236         //receive response from server
237         Deserialization::Deserialize(recv, retval);
238         if (retval != SECURITY_MANAGER_API_SUCCESS)
239             return SECURITY_MANAGER_ERROR_UNKNOWN;
240
241         return SECURITY_MANAGER_SUCCESS;;
242     });
243 }
244
245 SECURITY_MANAGER_API
246 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
247 {
248     using namespace SecurityManager;
249     MessageBuffer send, recv;
250
251     LogDebug("security_manager_get_app_pkgid() called");
252
253     return try_catch([&] {
254         //checking parameters
255
256         if (app_id == NULL) {
257             LogError("security_manager_app_get_pkgid: app_id is NULL");
258             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
259         }
260
261         if (pkg_id == NULL) {
262             LogError("security_manager_app_get_pkgid: pkg_id is NULL");
263             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
264         }
265
266         //put data into buffer
267         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
268         Serialization::Serialize(send, std::string(app_id));
269
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;
275         }
276
277         //receive response from server
278         Deserialization::Deserialize(recv, retval);
279         if (retval != SECURITY_MANAGER_API_SUCCESS)
280             return SECURITY_MANAGER_ERROR_UNKNOWN;
281
282         std::string pkgIdString;
283         Deserialization::Deserialize(recv, pkgIdString);
284         if (pkgIdString.empty()) {
285             LogError("Unexpected empty pkgId");
286             return SECURITY_MANAGER_ERROR_UNKNOWN;
287         }
288
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;
293         }
294
295         return SECURITY_MANAGER_SUCCESS;
296     });
297 }
298
299 static bool setup_smack(const char *label)
300 {
301     int labelSize = strlen(label);
302
303     // Set Smack label for open socket file descriptors
304
305     std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
306         opendir("/proc/self/fd"), closedir);
307     if (!dir.get()) {
308         LogError("Unable to read list of open file descriptors: " <<
309             strerror(errno));
310         return SECURITY_MANAGER_ERROR_UNKNOWN;
311     }
312
313     do {
314         errno = 0;
315         struct dirent *dirEntry = readdir(dir.get());
316         if (dirEntry == nullptr) {
317             if (errno == 0) // NULL return value also signals end of directory
318                 break;
319
320             LogError("Unable to read list of open file descriptors: " <<
321                 strerror(errno));
322             return SECURITY_MANAGER_ERROR_UNKNOWN;
323         }
324
325         // Entries with numerical names specify file descriptors, ignore the rest
326         if (!isdigit(dirEntry->d_name[0]))
327             continue;
328
329         struct stat statBuf;
330         int fd = atoi(dirEntry->d_name);
331         int ret = fstat(fd, &statBuf);
332         if (ret != 0) {
333             LogWarning("fstat failed on file descriptor " << fd << ": " <<
334                 strerror(errno));
335             continue;
336         }
337         if (S_ISSOCK(statBuf.st_mode)) {
338             ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
339             if (ret != 0) {
340                 LogError("Setting Smack label failed on file descriptor " <<
341                     fd << ": " << strerror(errno));
342                 return SECURITY_MANAGER_ERROR_UNKNOWN;
343             }
344
345             ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
346             if (ret != 0) {
347                 LogError("Setting Smack label failed on file descriptor " <<
348                     fd << ": " << strerror(errno));
349                 return SECURITY_MANAGER_ERROR_UNKNOWN;
350             }
351         }
352     } while (true);
353
354     // Set Smack label of current process
355     smack_set_label_for_self(label);
356
357     return SECURITY_MANAGER_SUCCESS;
358 }
359
360 SECURITY_MANAGER_API
361 int security_manager_set_process_label_from_appid(const char *app_id)
362 {
363     int ret;
364     std::string appLabel;
365
366     LogDebug("security_manager_set_process_label_from_appid() called");
367
368     if (smack_smackfs_path() == NULL)
369         return SECURITY_MANAGER_SUCCESS;
370
371     // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
372     //       are implemented.
373     std::string zoneId;
374     if (!getZoneIdFromPid(getpid(), zoneId)) {
375         LogError("Failed to get ID of zone");
376         return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
377     }
378
379     try {
380         appLabel = SecurityManager::zoneSmackLabelGenerate(
381                 SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
382
383     } catch (...) {
384         LogError("Failed to generate smack label for appId: " << app_id);
385         return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
386     }
387
388     if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
389         LogError("Failed to set smack label " << appLabel << " for current process");
390         return ret;
391     }
392
393     return SECURITY_MANAGER_SUCCESS;
394 }
395
396 SECURITY_MANAGER_API
397 int security_manager_set_process_groups_from_appid(const char *app_id)
398 {
399     using namespace SecurityManager;
400     MessageBuffer send, recv;
401     int ret;
402
403     LogDebug("security_manager_set_process_groups_from_appid() called");
404
405     return try_catch([&] {
406         //checking parameters
407
408         if (app_id == nullptr) {
409             LogError("app_id is NULL");
410             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
411         }
412
413         //put data into buffer
414         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
415         Serialization::Serialize(send, std::string(app_id));
416
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;
422         }
423
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;
429         }
430
431         //How many new groups?
432         int newGroupsCnt;
433         Deserialization::Deserialize(recv, newGroupsCnt);
434
435         //And how many groups do we belong to already?
436         int oldGroupsCnt;
437         ret = getgroups(0, nullptr);
438         if (ret == -1) {
439             LogError("Unable to get list of current supplementary groups: " <<
440                 strerror(errno));
441             return SECURITY_MANAGER_ERROR_UNKNOWN;
442         }
443         oldGroupsCnt = ret;
444
445         //Allocate an array for both old and new groups gids
446         std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
447         if (!groups.get()) {
448             LogError("Memory allocation failed.");
449             return SECURITY_MANAGER_ERROR_MEMORY;
450         }
451
452         //Get the old groups from process
453         ret = getgroups(oldGroupsCnt, groups.get());
454         if (ret == -1) {
455             LogError("Unable to get list of current supplementary groups: " <<
456                 strerror(errno));
457             return SECURITY_MANAGER_ERROR_UNKNOWN;
458         }
459
460         //Get the new groups from server response
461         for (int i = 0; i < newGroupsCnt; ++i) {
462             gid_t gid;
463             Deserialization::Deserialize(recv, gid);
464             groups.get()[oldGroupsCnt + i] = gid;
465             LogDebug("Adding process to group " << gid);
466         }
467
468         //Apply the modified groups list
469         ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
470         if (ret == -1) {
471             LogError("Unable to get list of current supplementary groups: " <<
472                 strerror(errno));
473             return SECURITY_MANAGER_ERROR_UNKNOWN;
474         }
475
476         return SECURITY_MANAGER_SUCCESS;
477     });
478 }
479
480 SECURITY_MANAGER_API
481 int security_manager_drop_process_privileges(void)
482 {
483     LogDebug("security_manager_drop_process_privileges() called");
484
485     int ret;
486     cap_t cap = cap_init();
487     if (!cap) {
488         LogError("Unable to allocate capability object");
489         return SECURITY_MANAGER_ERROR_MEMORY;
490     }
491
492     ret = cap_clear(cap);
493     if (ret) {
494         LogError("Unable to initialize capability object");
495         cap_free(cap);
496         return SECURITY_MANAGER_ERROR_UNKNOWN;
497     }
498
499     ret = cap_set_proc(cap);
500     if (ret) {
501         LogError("Unable to drop process capabilities");
502         cap_free(cap);
503         return SECURITY_MANAGER_ERROR_UNKNOWN;
504     }
505
506     cap_free(cap);
507     return SECURITY_MANAGER_SUCCESS;
508 }
509
510 SECURITY_MANAGER_API
511 int security_manager_prepare_app(const char *app_id)
512 {
513     LogDebug("security_manager_prepare_app() called");
514     int ret;
515
516     ret = security_manager_set_process_label_from_appid(app_id);
517     if (ret != SECURITY_MANAGER_SUCCESS)
518         return ret;
519
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;
524     }
525
526     ret = security_manager_drop_process_privileges();
527     return ret;
528 }
529
530 SECURITY_MANAGER_API
531 int security_manager_user_req_new(user_req **pp_req)
532 {
533     if (!pp_req)
534         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
535     try {
536         *pp_req = new user_req;
537     } catch (std::bad_alloc& ex) {
538         return SECURITY_MANAGER_ERROR_MEMORY;
539     }
540     return SECURITY_MANAGER_SUCCESS;
541 }
542
543 SECURITY_MANAGER_API
544 void security_manager_user_req_free(user_req *p_req)
545 {
546     delete p_req;
547 }
548
549 SECURITY_MANAGER_API
550 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
551 {
552     if (!p_req)
553         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
554
555     p_req->uid = uid;
556
557     return SECURITY_MANAGER_SUCCESS;
558 }
559
560 SECURITY_MANAGER_API
561 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
562 {
563     if (!p_req)
564         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
565
566     p_req->utype = static_cast<int>(utype);
567
568     return SECURITY_MANAGER_SUCCESS;
569 }
570
571 SECURITY_MANAGER_API
572 int security_manager_user_add(const user_req *p_req)
573 {
574     using namespace SecurityManager;
575     if (!p_req)
576         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
577
578     return try_catch([&] {
579         int retval;
580         ClientOffline offlineMode;
581         if (offlineMode.isOffline()) {
582             retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid(),
583                                                            false);
584         } else {
585             MessageBuffer send, recv;
586             //server is working
587
588             //put data into buffer
589             Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD));
590
591             Serialization::Serialize(send, p_req->uid);
592             Serialization::Serialize(send, p_req->utype);
593
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;
599             }
600
601             //receive response from server
602             Deserialization::Deserialize(recv, retval);
603         }
604         switch(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;
609         default:
610             return SECURITY_MANAGER_ERROR_UNKNOWN;
611         }
612     });
613 }
614
615 SECURITY_MANAGER_API
616 int security_manager_user_delete(const user_req *p_req)
617 {
618     using namespace SecurityManager;
619     MessageBuffer send, recv;
620     if (!p_req)
621         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
622     return try_catch([&] {
623
624         //put data into buffer
625         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE));
626
627         Serialization::Serialize(send, p_req->uid);
628
629
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;
635         }
636
637         //receive response from server
638         Deserialization::Deserialize(recv, retval);
639         switch(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;
644         default:
645             return SECURITY_MANAGER_ERROR_UNKNOWN;
646         }
647     });
648 }
649
650
651 /***************************POLICY***************************************/
652
653 SECURITY_MANAGER_API
654 int security_manager_policy_update_req_new(policy_update_req **pp_req)
655 {
656     if (!pp_req)
657         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
658
659     try {
660         *pp_req = new policy_update_req;
661     } catch (std::bad_alloc& ex) {
662         return SECURITY_MANAGER_ERROR_MEMORY;
663     }
664
665     return SECURITY_MANAGER_SUCCESS;
666 }
667
668 SECURITY_MANAGER_API
669 void security_manager_policy_update_req_free(policy_update_req *p_req)
670 {
671     delete p_req;
672 }
673
674 SECURITY_MANAGER_API
675 int security_manager_policy_update_send(policy_update_req *p_req)
676 {
677     using namespace SecurityManager;
678     MessageBuffer send, recv;
679
680     if (p_req == nullptr || p_req->units.size() == 0)
681         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
682
683     return try_catch([&] {
684
685         //put request into buffer
686         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
687         Serialization::Serialize(send, p_req->units);
688
689         //send it to server
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;
694         }
695
696         //receive response from server
697         Deserialization::Deserialize(recv, retval);
698         switch(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;
705             default:
706                 return SECURITY_MANAGER_ERROR_UNKNOWN;
707         }
708     });
709 }
710
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,
715         size_t *p_size)
716 {
717     using namespace SecurityManager;
718     MessageBuffer send, recv;
719
720     if (ppp_privs_policy == nullptr
721         || p_size == nullptr
722         || p_filter == nullptr)
723         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
724
725     return try_catch([&] {
726         //put request into buffer
727         Serialization::Serialize(send, static_cast<int>(call_type));
728         Serialization::Serialize(send, *p_filter);
729         //send it to server
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;
734         }
735         //receive response from server
736         Deserialization::Deserialize(recv, retval);
737         switch (retval) {
738             case SECURITY_MANAGER_API_SUCCESS: {
739                 //extract and allocate buffers for privs policy entries
740                 int entriesCnt = 0;
741                 policy_entry **entries = nullptr;
742                 try {
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]);
748                     };
749                 } catch (...) {
750                     LogError("Error while parsing server response");
751                     for (int i = 0; i < entriesCnt; ++i)
752                         delete(entries[i]);
753                     delete[] entries;
754                     return SECURITY_MANAGER_ERROR_UNKNOWN;
755                 }
756                 *p_size = entriesCnt;
757                 *ppp_privs_policy = entries;
758                 return SECURITY_MANAGER_SUCCESS;
759             }
760             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
761                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
762
763             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
764                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
765
766             default:
767                 return SECURITY_MANAGER_ERROR_UNKNOWN;
768         }
769     });
770 }
771
772 SECURITY_MANAGER_API
773 int security_manager_get_configured_policy_for_admin(
774         policy_entry *p_filter,
775         policy_entry ***ppp_privs_policy,
776         size_t *p_size)
777 {
778     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
779 }
780
781 SECURITY_MANAGER_API
782 int security_manager_get_configured_policy_for_self(
783         policy_entry *p_filter,
784         policy_entry ***ppp_privs_policy,
785         size_t *p_size)
786 {
787     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
788 }
789
790 SECURITY_MANAGER_API
791 int security_manager_get_policy(
792         policy_entry *p_filter,
793         policy_entry ***ppp_privs_policy,
794         size_t *p_size)
795 {
796     return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
797 };
798
799 SECURITY_MANAGER_API
800 int security_manager_policy_entry_new(policy_entry **p_entry)
801 {
802     if (!p_entry)
803         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
804
805     try {
806         *p_entry = new policy_entry;
807     } catch (std::bad_alloc& ex) {
808         return SECURITY_MANAGER_ERROR_MEMORY;
809     }
810
811     return SECURITY_MANAGER_SUCCESS;
812 }
813
814 SECURITY_MANAGER_API
815 void security_manager_policy_entry_free(policy_entry *p_entry)
816 {
817     delete p_entry;
818 }
819
820 SECURITY_MANAGER_API
821 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
822 {
823     if (!p_entry)
824         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
825     p_entry->appId = app_id;
826     return  SECURITY_MANAGER_SUCCESS;
827 }
828
829 SECURITY_MANAGER_API
830 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
831 {
832     if (!p_entry)
833         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
834     p_entry->user = user;
835     return  SECURITY_MANAGER_SUCCESS;
836 }
837
838 SECURITY_MANAGER_API
839 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
840 {
841     if (!p_entry)
842         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
843     p_entry->privilege = privilege;
844     return  SECURITY_MANAGER_SUCCESS;
845 }
846
847 SECURITY_MANAGER_API
848 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
849 {
850     if (!p_entry)
851         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
852     p_entry->currentLevel = policy_level;
853     p_entry->maxLevel = EMPTY;
854     return  SECURITY_MANAGER_SUCCESS;
855 }
856
857 SECURITY_MANAGER_API
858 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
859 {
860     if (!p_entry)
861         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
862     p_entry->maxLevel = policy_level;
863     p_entry->currentLevel = EMPTY;
864     return  SECURITY_MANAGER_SUCCESS;
865 }
866
867 SECURITY_MANAGER_API
868 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
869 {
870     if (!p_entry || !p_req)
871         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
872     p_req->units.push_back(p_entry);
873
874     return  SECURITY_MANAGER_SUCCESS;
875 }
876
877 SECURITY_MANAGER_API
878 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
879 {
880     return p_entry ? p_entry->user.c_str() : nullptr;
881 }
882
883 SECURITY_MANAGER_API
884 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
885 {
886     return p_entry ? p_entry->appId.c_str() : nullptr;
887 }
888 SECURITY_MANAGER_API
889 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
890 {
891     return p_entry ? p_entry->privilege.c_str() : nullptr;
892 }
893 SECURITY_MANAGER_API
894 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
895 {
896     return p_entry ? p_entry->currentLevel.c_str() : nullptr;
897 }
898
899 SECURITY_MANAGER_API
900 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
901 {
902     return p_entry ? p_entry->maxLevel.c_str() : nullptr;
903 }
904
905 SECURITY_MANAGER_API
906 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
907 {
908     for (size_t i = 0; i < size; i++) {
909         delete &p_entries[i];
910     }
911     delete [] p_entries;
912 }
913
914 SECURITY_MANAGER_API
915 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
916 {
917     using namespace SecurityManager;
918     MessageBuffer send, recv;
919     if (!levels || !levels_count)
920         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
921     return try_catch([&] {
922
923         //put data into buffer
924         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
925
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;
931         }
932
933         //receive response from server
934         Deserialization::Deserialize(recv, retval);
935
936         switch(retval) {
937             case SECURITY_MANAGER_API_SUCCESS:
938                 // success - continue
939                 break;
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;
944             default:
945                 return SECURITY_MANAGER_ERROR_UNKNOWN;
946         }
947
948         int count;
949         Deserialization::Deserialize(recv, count);
950         *levels_count = count;
951         LogInfo("Number of policy descriptions: " << *levels_count);
952
953         char **array = new char *[*levels_count];
954
955         for (unsigned int i = 0; i < *levels_count; ++i) {
956             std::string level;
957             Deserialization::Deserialize(recv, level);
958
959             if (level.empty()) {
960                 LogError("Unexpected empty level");
961                 return SECURITY_MANAGER_ERROR_UNKNOWN;
962             }
963
964             array[i] = strdup(level.c_str());
965             if (array[i] == nullptr)
966                 return SECURITY_MANAGER_ERROR_MEMORY;
967         }
968
969         *levels = array;
970
971         return SECURITY_MANAGER_SUCCESS;
972     });
973 }
974
975 SECURITY_MANAGER_API
976 void security_manager_policy_levels_free(char **levels, size_t levels_count)
977 {
978     for (unsigned int i = 0; i < levels_count; i++)
979         free(levels[i]);
980
981     delete[] levels;
982 }
983
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)
989 {
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);
996
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;
1002     }
1003
1004     //receive response from server
1005     Deserialization::Deserialize(recv, retval);
1006
1007     switch(retval) {
1008         case SECURITY_MANAGER_API_SUCCESS:
1009             // success - continue
1010             break;
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;
1015         default:
1016             return SECURITY_MANAGER_ERROR_UNKNOWN;
1017     }
1018
1019     unsigned int count;
1020     Deserialization::Deserialize(recv, count);
1021     LogInfo("Number of privilege mappings: " << count);
1022     size_t i = 0;
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);
1026
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;
1033         }
1034
1035         mappings_ptr.get()[i] = strdup(privilege_mapping.c_str());
1036         if (mappings_ptr.get()[i] == nullptr)
1037             return SECURITY_MANAGER_ERROR_MEMORY;
1038     }
1039
1040     *privileges_mappings = mappings_ptr.release();
1041     *mappings_count = count;
1042
1043     return SECURITY_MANAGER_SUCCESS;
1044 }
1045
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)
1053 {
1054     if (from_version == nullptr || privileges_mappings == nullptr || mappings_count == nullptr) {
1055         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1056     }
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);
1062         }
1063         if (to_version == nullptr)
1064             to_version = "";
1065         LogDebug("security_manager_get_privileges_mapping() called with :"
1066                  " from_version = " << from_version << " to_version = " << to_version <<
1067                  " privileges_count " << privilegesToMap.size());
1068
1069         return get_privileges_mapping(from_version, to_version, privilegesToMap,
1070                                       privileges_mappings, mappings_count);
1071
1072     });
1073 }
1074 SECURITY_MANAGER_API
1075 void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
1076 {
1077     for(size_t i = 0; i < mappings_count; i++)
1078         free(privileges_mappings[i]);
1079     delete [] privileges_mappings;
1080 }
1081
1082 SECURITY_MANAGER_API
1083 int security_manager_groups_get(char ***groups, size_t *groups_count)
1084 {
1085     using namespace SecurityManager;
1086     MessageBuffer send, recv;
1087     if (!groups || !groups_count)
1088         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1089     return try_catch([&] {
1090
1091         //put data into buffer
1092         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GROUPS_GET));
1093
1094         //send buffer to server
1095         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
1096         if (retval != SECURITY_MANAGER_API_SUCCESS) {
1097             LogError("Error in sendToServer. Error code: " << retval);
1098             return SECURITY_MANAGER_ERROR_UNKNOWN;
1099         }
1100
1101         //receive response from server
1102         Deserialization::Deserialize(recv, retval);
1103
1104         switch(retval) {
1105             case SECURITY_MANAGER_API_SUCCESS:
1106                 // success - continue
1107                 break;
1108             case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1109                 return SECURITY_MANAGER_ERROR_MEMORY;
1110             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1111                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1112             default:
1113                 return SECURITY_MANAGER_ERROR_UNKNOWN;
1114         }
1115
1116         std::vector<std::string> vgroups;
1117         Deserialization::Deserialize(recv, vgroups);
1118         const auto vgroups_size = vgroups.size();
1119         LogInfo("Number of groups: " << vgroups_size);
1120
1121         std::unique_ptr<char *, std::function<void(char **)>> array(
1122             static_cast<char **>(calloc(vgroups_size, sizeof(char *))),
1123             std::bind(security_manager_groups_free, std::placeholders::_1, vgroups_size));
1124
1125         if (array == nullptr)
1126             return SECURITY_MANAGER_ERROR_MEMORY;
1127
1128         for (size_t i = 0; i < vgroups_size; ++i) {
1129             const auto &group = vgroups.at(i);
1130
1131             if (group.empty()) {
1132                 LogError("Unexpected empty group");
1133                 return SECURITY_MANAGER_ERROR_UNKNOWN;
1134             }
1135
1136             array.get()[i] = strdup(group.c_str());
1137             if (array.get()[i] == nullptr)
1138                 return SECURITY_MANAGER_ERROR_MEMORY;
1139         }
1140
1141         *groups_count = vgroups_size;
1142         *groups = array.release();
1143
1144         return SECURITY_MANAGER_SUCCESS;
1145     });
1146 }
1147
1148 SECURITY_MANAGER_API
1149 void security_manager_groups_free(char **groups, size_t groups_count)
1150 {
1151     if (groups == nullptr)
1152         return;
1153
1154     for (size_t i = 0; i < groups_count; i++)
1155         free(groups[i]);
1156
1157     free(groups);
1158 }