4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Kidong Kim <kd0228.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
26 #include <sys/types.h>
38 #include <sys/smack.h>
39 #include <linux/capability.h>
40 #include <sys/capability.h>
45 #include "privilege-control.h"
46 #include "access-db.h"
52 #define DEVELOPER_GID 5100
53 #define DEVELOPER_UID 5100
55 #define APP_USER_NAME "app"
56 #define DEV_USER_NAME "developer"
58 #define APP_HOME_DIR TOSTRING(HOMEDIR) "/app"
59 #define DEV_HOME_DIR TOSTRING(HOMEDIR) "/developer"
61 #define APP_GROUP_PATH TOSTRING(SHAREDIR) "/app_group_list"
62 #define DEV_GROUP_PATH TOSTRING(SHAREDIR) "/dev_group_list"
64 #define SMACK_SRC_FILE_SUFFIX "_src_file"
65 #define SMACK_SRC_DIR_SUFFIX "_src_dir"
66 #define SMACK_DATA_SUFFIX "_data"
67 #define WRT_BASE_DEVCAP "WRT"
68 #define WRT_CLIENT_PATH "/usr/bin/wrt-client"
70 #define TIZEN_PRIVILEGE_ANTIVIRUS "http://tizen.org/privilege/antivirus"
71 #define TIZEN_PRIVILEGE_APPSETTING "http://tizen.org/privilege/appsetting"
72 #define PATH_RULES_PUBLIC_RO "PATH_RULES_PUBLIC_RO.smack"
73 #define PATH_RULES_GROUP_RW "PATH_RULES_GROUP_RW.smack"
89 typedef int (*label_decision_fn)(const FTSENT*);
95 __attribute__ ((destructor))
96 static void libprivilege_destructor()
98 SECURE_C_LOGD("Entering function: %s.", __func__);
102 API int perm_begin(void)
104 SECURE_C_LOGD("Entering function: %s.", __func__);
105 return rdb_modification_start();
108 API int perm_end(void)
110 SECURE_C_LOGD("Entering function: %s.", __func__);
112 return rdb_modification_finish();
115 API int control_privilege(void)//deprecated
117 SECURE_C_LOGD("Entering function: %s.", __func__);
119 if(getuid() == APP_UID) // current user is 'app'
120 return PC_OPERATION_SUCCESS;
122 if(perm_app_set_privilege("org.tizen.", NULL, NULL) == PC_OPERATION_SUCCESS)
123 return PC_OPERATION_SUCCESS;
125 C_LOGE("perm_app_set_privilege failed (not permitted).");
126 return PC_ERR_NOT_PERMITTED;
131 * TODO: this function should be moved to libsmack in open-source.
133 API int get_smack_label_from_process(pid_t pid, char *smack_label)
135 SECURE_C_LOGD("Entering function: %s. Params: pid=%i", __func__, pid);
139 int PATH_MAX_LEN = 64;
140 char path[PATH_MAX_LEN + 1];
143 C_LOGE("invalid param pid.");
144 ret = PC_ERR_INVALID_PARAM;
148 if(smack_label == NULL) {
149 C_LOGE("Invalid param smack_label (NULL).");
150 ret = PC_ERR_INVALID_PARAM;
154 bzero(smack_label, SMACK_LABEL_LEN + 1);
155 if (!have_smack()) { // If no smack just return success with empty label
156 C_LOGD("No SMACK. Returning empty label");
157 ret = PC_OPERATION_SUCCESS;
161 bzero(path, PATH_MAX_LEN + 1);
162 snprintf(path, PATH_MAX_LEN, "/proc/%d/attr/current", pid);
163 fd = open(path, O_RDONLY);
165 SECURE_C_LOGE("Cannot open file %s (errno: %s)", path, strerror(errno));
166 ret = PC_ERR_FILE_OPERATION;
170 ret = read(fd, smack_label, SMACK_LABEL_LEN);
172 SECURE_C_LOGE("Cannot read from file %s", path);
173 ret = PC_ERR_FILE_OPERATION;
177 SECURE_C_LOGD("smack_label=%s", smack_label);
179 ret = PC_OPERATION_SUCCESS;
185 API int smack_pid_have_access(pid_t pid,
187 const char *access_type)
189 SECURE_C_LOGD("Entering function: %s. Params: pid=%i, object=%s, access_type=%s",
190 __func__, pid, object, access_type);
193 char pid_subject_label[SMACK_LABEL_LEN + 1];
195 cap_flag_value_t cap_v;
198 C_LOGD("No SMACK. Return access granted");
203 C_LOGE("Invalid pid.");
208 C_LOGE("Invalid object param.");
212 if(access_type == NULL) {
213 C_LOGE("Invalid access_type param");
217 //get SMACK label of process
218 ret = get_smack_label_from_process(pid, pid_subject_label);
219 if (PC_OPERATION_SUCCESS != ret) {
220 SECURE_C_LOGE("get_smack_label_from_process %d failed: %d", pid, ret);
223 SECURE_C_LOGD("pid %d has label: %s", pid, pid_subject_label);
225 // do not call smack_have_access() if label is empty
226 if (pid_subject_label[0] != '\0') {
227 ret = smack_have_access(pid_subject_label, object, access_type);
229 C_LOGE("smack_have_access failed.");
232 if ( 1 == ret ) { // smack_have_access return 1 (access granted)
233 C_LOGD("smack_have_access returned 1 (access granted)");
238 // smack_have_access returned 0 (access denied). Now CAP_MAC_OVERRIDE should be checked
239 C_LOGD("smack_have_access returned 0 (access denied)");
240 cap = cap_get_pid(pid);
242 C_LOGE("cap_get_pid failed");
245 ret = cap_get_flag(cap, CAP_MAC_OVERRIDE, CAP_EFFECTIVE, &cap_v);
247 C_LOGE("cap_get_flag failed");
251 if (cap_v == CAP_SET) {
252 C_LOGD("pid %d has CAP_MAC_OVERRIDE", pid);
256 C_LOGD("pid %d doesn't have CAP_MAC_OVERRIDE", pid);
263 static int get_user_groups(uid_t user_id, int *nbgroup, gid_t **groups_list)
265 gid_t *groups = NULL;
267 C_LOGD("Enter function: %s", __func__);
269 if ((!groups_list) || (!nbgroup))
270 return PC_ERR_INVALID_OPERATION;
271 pw = getpwuid(user_id);
273 C_LOGE("getgrouplist fails : Invalid User ID %d",user_id);
274 return PC_ERR_INVALID_OPERATION;
277 //First call is done with *ngroup = 0 to get the number of groups found for the user (Usefull for next malloc operation). It should return -1 in this case.
278 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, nbgroup) != -1)
279 return PC_ERR_INVALID_OPERATION;
281 C_LOGD("getgrouplist %s user is member of %d groups ",pw->pw_name,*nbgroup);
282 groups = malloc(*nbgroup * sizeof (gid_t));
284 return PC_ERR_INVALID_OPERATION;
285 //Second call is done with the suitable ngroup value and structure groups allocated.
286 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, nbgroup) == -1) {
288 C_LOGE("getgrouplist fails %d",nbgroup);
289 return PC_ERR_INVALID_OPERATION;
291 *groups_list = groups;
292 return PC_OPERATION_SUCCESS;
295 static int set_dac(const char *smack_label, const char *pkg_name)
297 SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s, pkg_name=%s",
298 __func__, smack_label, pkg_name);
300 uid_t t_uid = -1; // uid of current process
301 gid_t *glist = NULL; // group list
302 int glist_cnt = 0; // for group list
306 unsigned *additional_gids = NULL;
309 * initialize user structure
311 C_LOGD("Initialize user structure");
312 memset(usr.user_name, 0x00, 10);
313 memset(usr.home_dir, 0x00, 64);
314 memset(usr.group_list, 0x00, 64);
319 C_LOGD("Current uid is %d", t_uid);
321 if(t_uid == 0) // current user is 'root'
323 if(!strncmp(pkg_name, "developer", 9))
325 strncpy(usr.user_name, DEV_USER_NAME, sizeof(usr.user_name));
326 usr.uid = DEVELOPER_UID;
327 usr.gid = DEVELOPER_GID;
328 strncpy(usr.home_dir, DEV_HOME_DIR, sizeof(usr.home_dir));
329 strncpy(usr.group_list, DEV_GROUP_PATH, sizeof(usr.group_list));
333 strncpy(usr.user_name, APP_USER_NAME, sizeof(usr.user_name));
336 strncpy(usr.home_dir, APP_HOME_DIR, sizeof(usr.home_dir));
340 * get group information
342 C_LOGD("get group information");
343 if (get_user_groups(usr.uid, &glist_cnt, &glist)) {
344 result = PC_ERR_FILE_OPERATION; // return -1
351 result = get_app_gids(smack_label, &additional_gids, &cnt);
352 if (result != PC_OPERATION_SUCCESS)
356 glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + cnt));
357 if (glist_new == NULL) {
358 result = PC_ERR_MEM_OPERATION; // return -2
359 C_LOGE("Memory allocation failed");
363 for (i = 0; i < cnt; ++i) {
364 C_LOGD("Additional GID based on enabled permissions: %u", additional_gids[i]);
365 glist[glist_cnt++] = additional_gids[i];
373 C_LOGD("Adding process to the following groups:");
374 for(i=0; i<glist_cnt; ++i) {
375 SECURE_C_LOGD("glist [ %d ] = %d", i, glist[i]);
377 C_LOGD("Calling setgroups()");
378 if(setgroups(glist_cnt, glist) != 0)
380 C_LOGE("setgroups failed");
381 result = PC_ERR_NOT_PERMITTED; // return -3
391 * setuid() & setgid()
393 C_LOGD("setgid( %d ) & setuid( %d )", usr.gid, usr.uid);
394 if(setgid(usr.gid) != 0) // fail
396 C_LOGE("Failed to execute setgid().");
397 result = PC_ERR_INVALID_OPERATION;
400 if(setuid(usr.uid) != 0) // fail
402 C_LOGE("Failed to execute setuid().");
403 result = PC_ERR_INVALID_OPERATION;
407 SECURE_C_LOGD("setenv(): USER = %s, HOME = %s", usr.user_name, usr.home_dir);
408 if(setenv("USER", usr.user_name, 1) != 0) //fail
410 C_LOGE("Failed to execute setenv() [USER].");
411 result = PC_ERR_INVALID_OPERATION;
414 if(setenv("HOME", usr.home_dir, 1) != 0) // fail
416 C_LOGE("Failed to execute setenv() [HOME].");
417 result = PC_ERR_INVALID_OPERATION;
421 else // current user is not only 'root' but 'app'
423 C_LOGE("Current user is NOT root");
424 result = PC_ERR_NOT_PERMITTED; // return -3
428 result = PC_OPERATION_SUCCESS;
433 free(additional_gids);
439 * Get SMACK label from EXEC label of a file.
440 * SMACK label should be freed by caller
442 * @param path file path to take label from
443 * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
445 static int get_smack_from_binary(char **smack_label, const char* path, app_type_t type)
447 SECURE_C_LOGD("Entering function: %s. Params: path=%s, type=%d",
448 __func__, path, type);
452 if (type == PERM_APP_TYPE_WRT
453 || type == PERM_APP_TYPE_WRT_PARTNER
454 || type == PERM_APP_TYPE_WRT_PLATFORM) {
455 ret = smack_lgetlabel(path, smack_label, SMACK_LABEL_EXEC);
457 ret = smack_getlabel(path, smack_label, SMACK_LABEL_EXEC);
460 C_LOGE("Getting exec label from file %s failed", path);
461 return PC_ERR_INVALID_OPERATION;
464 return PC_OPERATION_SUCCESS;
468 * Set process SMACK label.
469 * This function is emulating EXEC label behavior of SMACK for programs
470 * run by dlopen/dlsym instead of execv.
473 * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
475 static int set_smack_for_self (char *smack_label)
477 SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s",
478 __func__, smack_label);
481 if (smack_label == NULL) {
482 /* No label to set, just return with success */
483 C_LOGD("No label to set, just return with success.");
484 ret = PC_OPERATION_SUCCESS;
487 SECURE_C_LOGD("smack_label=%s", smack_label);
489 ret = smack_set_label_for_self(smack_label);
490 C_LOGD("smack_set_label_for_self returned %d", ret);
492 ret = PC_OPERATION_SUCCESS;
498 static int is_widget(const char* path)
500 SECURE_C_LOGD("Entering function: %s. Params: path=%s",
502 char buf[sizeof(WRT_CLIENT_PATH)];
505 ret = readlink(path, buf, sizeof(WRT_CLIENT_PATH));
507 C_LOGD("readlink(%s) returned error: %s. Assuming that app is not a widget", path, strerror(errno));
508 else if (ret == sizeof(WRT_CLIENT_PATH))
509 C_LOGD("%s is not a widget", path);
510 if (ret == -1 || ret == sizeof(WRT_CLIENT_PATH))
513 C_LOGD("buf=%s", buf);
515 ret = !strcmp(WRT_CLIENT_PATH, buf);
516 C_LOGD("%s is %s widget", path, ret ? "a" : "not a");
521 * Partially verify, that the type given for app is correct.
522 * This function will use some heuristics to check whether the app type is right.
523 * It is intended for security hardening to catch privilege setting for the
524 * app type not corresponding to the actual binary.
525 * Beware - when it detects an anomaly, the whole process will be terminated.
527 * @param type claimed application type
528 * @param path file path to executable
529 * @return return void on success, terminate the process on error
531 static app_type_t verify_app_type(const char* type, const char* path)
533 SECURE_C_LOGD("Entering function: %s. Params: type=%s, path=%s",
534 __func__, type, path);
536 /* TODO: this should actually be treated as error, but until the old
537 * set_privilege API is removed, it must be ignored */
539 C_LOGD("PKG_TYPE_OTHER");
540 return APP_TYPE_OTHER; /* good */
543 if (is_widget(path)) {
544 if (!strcmp(type, "wgt")) {
545 C_LOGD("PKG_TYPE_WRT");
546 return PERM_APP_TYPE_WRT; /* good */
547 } else if (!strcmp(type, "wgt_partner")) {
548 C_LOGD("PKG_TYPE_WRT_PARTNER");
549 return PERM_APP_TYPE_WRT_PARTNER; /* good */
550 } else if (!strcmp(type, "wgt_platform")) {
551 C_LOGD("PKG_TYPE_WRT_PLATFORM");
552 return PERM_APP_TYPE_WRT_PLATFORM; /* good */
556 if (type == NULL || (strcmp(type, "wgt")
557 && strcmp(type, "wgt_partner")
558 && strcmp(type, "wgt_platform"))){
559 C_LOGD("PKG_TYPE_OTHER");
560 return PERM_APP_TYPE_OTHER; /* good */
565 C_LOGE("EXIT_FAILURE");
569 API int set_app_privilege(const char* name, const char* type, const char* path)//deprecated
571 SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
572 __func__, name, type, path);
574 return perm_app_set_privilege(name, type, path);
577 API int perm_app_set_privilege(const char* name, const char* type, const char* path)
579 SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
580 __func__, name, type, path);
582 //SECURE_C_LOGD("Function params: name = %s, type = %s, path = %s", name, type, path);
583 int ret = PC_OPERATION_SUCCESS;
584 char *smack_label AUTO_FREE;
587 C_LOGE("Error invalid parameter");
588 return PC_ERR_INVALID_PARAM;
591 if (path != NULL && have_smack()) {
592 ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
593 if (ret != PC_OPERATION_SUCCESS)
596 ret = set_smack_for_self(smack_label);
597 if (ret != PC_OPERATION_SUCCESS)
601 if (path != NULL && !have_smack()) {
602 ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
603 if (ret != PC_OPERATION_SUCCESS)
607 return set_dac(smack_label, name);
610 API int set_privilege(const char* pkg_name)//deprecated
612 SECURE_C_LOGD("Entering function: %s. Params: pkg_name=%s",
615 return perm_app_set_privilege(pkg_name, NULL, NULL);
618 static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix, bool is_early)
620 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, perm=%s, suffix=%s, is_early=%d",
621 __func__, app_type, perm, suffix, is_early);
623 const char* app_type_prefix = NULL;
624 char* perm_basename = NULL;
627 if (perm == NULL || strlen(perm) == 0) {
628 C_LOGE("Empty permission name.");
629 return PC_ERR_INVALID_PARAM;
632 app_type_prefix = app_type_group_name(app_type);
634 ret = base_name_from_perm(perm, &perm_basename);
635 if (ret != PC_OPERATION_SUCCESS) {
636 C_LOGE("Couldn't get permission basename.");
641 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s%s",
642 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
643 perm_basename, "_early", suffix);
646 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
647 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
648 perm_basename, suffix);
651 C_LOGE("asprintf failed.");
652 return PC_ERR_MEM_OPERATION;
655 C_LOGD("Path=%s", *path);
657 return PC_OPERATION_SUCCESS;
660 static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
662 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
663 __func__, app_label, app_type, perm);
666 char* path AUTO_FREE;
667 FILE* file AUTO_FCLOSE;
670 ret = perm_file_path(&path, app_type, perm, ".dac", 0);
671 if (ret != PC_OPERATION_SUCCESS) {
672 C_LOGD("No dac config file for permission %s", perm);
676 SECURE_C_LOGD("Opening file %s.", path);
677 file = fopen(path, "r");
679 C_LOGW("fopen failed.");
680 return PC_OPERATION_SUCCESS;
683 while (fscanf(file, "%d\n", &gid) == 1) {
684 SECURE_C_LOGD("Adding app_id %s to group %d", app_label, gid);
685 ret = add_app_gid(app_label, gid);
686 if (ret != PC_OPERATION_SUCCESS) {
687 C_LOGE("add_app_gid failed");
692 return PC_OPERATION_SUCCESS;
695 static int label_all(const FTSENT* ftsent UNUSED)
697 SECURE_C_LOGD("Entering function: %s.", __func__);
699 return DECISION_LABEL;
702 static int label_execs(const FTSENT* ftsent)
704 SECURE_C_LOGD("Entering function: %s.", __func__);
706 C_LOGD("Mode = %d", ftsent->fts_statp->st_mode);
707 // label only regular executable files
708 if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
709 return DECISION_LABEL;
710 return DECISION_SKIP;
713 static int label_dirs(const FTSENT* ftsent)
715 SECURE_C_LOGD("Entering function: %s.", __func__);
717 // label only directories
718 if (S_ISDIR(ftsent->fts_statp->st_mode))
719 return DECISION_LABEL;
720 return DECISION_SKIP;
723 static int label_links_to_execs(const FTSENT* ftsent)
725 SECURE_C_LOGD("Entering function: %s.", __func__);
728 char* target AUTO_FREE;
730 // check if it's a link
731 if ( !S_ISLNK(ftsent->fts_statp->st_mode))
732 return DECISION_SKIP;
734 target = realpath(ftsent->fts_path, NULL);
736 SECURE_C_LOGE("Getting link target for %s failed (Error = %s)", ftsent->fts_path, strerror(errno));
737 return PC_ERR_FILE_OPERATION;
739 if (-1 == stat(target, &buf)) {
740 SECURE_C_LOGE("stat failed for %s (Error = %s", target, strerror(errno));
741 return PC_ERR_FILE_OPERATION;
743 // skip if link target is not a regular executable file
744 if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
745 SECURE_C_LOGD("%s is not a regular executable file. Skipping.", target);
746 return DECISION_SKIP;
749 return DECISION_LABEL;
752 static int dir_set_smack_r(const char *path, const char* label,
753 enum smack_label_type type, label_decision_fn fn)
755 SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, type=%d",
756 __func__, path, label, type);
758 const char* path_argv[] = {path, NULL};
759 FTS *fts AUTO_FTS_CLOSE;
763 fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
765 C_LOGE("fts_open failed.");
766 return PC_ERR_FILE_OPERATION;
769 while ((ftsent = fts_read(fts)) != NULL) {
770 /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
771 if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
772 C_LOGE("FTS_ERR error or failed stat(2) (FTS_NS)");
773 return PC_ERR_FILE_OPERATION;
778 C_LOGE("fn(ftsent) failed.");
782 if (ret == DECISION_LABEL) {
783 C_LOGD("smack_lsetlabel (label: %s (type: %d), path: %s)", label, type, ftsent->fts_path);
784 if (smack_lsetlabel(ftsent->fts_path, label, type) != 0) {
785 C_LOGE("smack_lsetlabel failed.");
786 return PC_ERR_FILE_OPERATION;
791 /* If last call to fts_read() set errno, we need to return error. */
793 C_LOGE("Last errno from fts_read: %s", strerror(errno));
794 return PC_ERR_FILE_OPERATION;
796 return PC_OPERATION_SUCCESS;
798 API char* app_id_from_socket(int sockfd)//deprecated
800 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
803 return perm_app_id_from_socket(sockfd);
806 API char* perm_app_id_from_socket(int sockfd)
808 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
812 C_LOGD("No SMACK. Returning NULL.");
819 ret = smack_new_label_from_socket(sockfd, &app_id);
821 C_LOGE("smack_new_label_from_socket failed");
825 SECURE_C_LOGD("app_id = %s", app_id);
831 API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
833 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
836 return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, true);
839 API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
841 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
844 return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, false);
847 API int perm_app_setup_permissions(const char* pkg_id, app_type_t app_type,
848 const char** perm_list)
850 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
851 __func__, pkg_id, app_type);
852 return perm_app_enable_permissions(pkg_id, app_type, perm_list, true);
855 API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
857 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
858 __func__, pkg_id, app_type, persistent);
860 return perm_app_enable_permissions(pkg_id, app_type, perm_list, persistent);
863 API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type,
864 const char** perm_list, bool persistent)
866 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
867 __func__, pkg_id, app_type, persistent);
871 if (!smack_label_is_valid(pkg_id)) {
872 C_LOGE("Invalid param app_id.");
873 return PC_ERR_INVALID_PARAM;
876 if (perm_list == NULL) {
877 C_LOGE("Invalid perm_list (NULL).");
878 return PC_ERR_INVALID_PARAM;
881 if (app_type_group_name(app_type) == NULL) {
882 C_LOGE("Unknown app type.");
883 return PC_ERR_INVALID_PARAM;
886 /* Add permission to DAC */
887 for (i = 0; perm_list[i] != NULL; ++i) {
888 ret = perm_to_dac(pkg_id, app_type, perm_list[i]);
889 if (ret != PC_OPERATION_SUCCESS) {
890 C_LOGE("perm_to_dac failed");
895 /* Enable the permissions: */
896 ret = rdb_enable_app_permissions(pkg_id, app_type, perm_list,
897 !((bool)persistent));
898 if (ret != PC_OPERATION_SUCCESS) {
899 C_LOGE("RDB rdb_enable_app_permissions failed with: %d", ret);
903 return PC_OPERATION_SUCCESS;
906 API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
908 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
909 __func__, pkg_id, app_type);
911 return perm_app_disable_permissions(pkg_id, app_type, perm_list);
914 API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
916 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
917 __func__, pkg_id, app_type);
920 if (!smack_label_is_valid(pkg_id)) {
921 C_LOGE("Invalid param app_id.");
922 return PC_ERR_INVALID_PARAM;
925 if (perm_list == NULL) {
926 C_LOGE("Invalid perm_list (NULL).");
927 return PC_ERR_INVALID_PARAM;
930 if (app_type_group_name(app_type) == NULL) {
931 C_LOGE("Unknown app type.");
932 return PC_ERR_INVALID_PARAM;
935 ret = rdb_disable_app_permissions(pkg_id, app_type, perm_list);
936 if (ret != PC_OPERATION_SUCCESS) {
937 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
941 return PC_OPERATION_SUCCESS;
944 API int app_revoke_permissions(const char* pkg_id)//deprecated
946 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
947 return perm_app_revoke_permissions(pkg_id);
950 API int perm_app_revoke_permissions(const char* pkg_id)
952 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
955 if (!smack_label_is_valid(pkg_id)) {
956 C_LOGE("Invalid param app_id.");
957 return PC_ERR_INVALID_PARAM;
960 ret = rdb_revoke_app_permissions(pkg_id);
961 if (ret != PC_OPERATION_SUCCESS) {
962 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
966 return PC_OPERATION_SUCCESS;
969 API int app_reset_permissions(const char* pkg_id)//deprecated
971 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
974 return perm_app_reset_permissions(pkg_id);
977 API int perm_app_reset_permissions(const char* pkg_id)
979 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
983 if (!smack_label_is_valid(pkg_id)) {
984 C_LOGE("Invalid param pkg_id.");
985 return PC_ERR_INVALID_PARAM;
988 ret = rdb_reset_app_permissions(pkg_id);
989 if (ret != PC_OPERATION_SUCCESS) {
990 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
994 return PC_OPERATION_SUCCESS;
997 API int perm_app_has_permission(const char *pkg_id,
999 const char *permission_name,
1002 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, permission_name=%s",
1003 __func__, pkg_id, app_type, permission_name);
1005 const char *app_group = app_type_group_name(app_type);
1007 if (app_group == NULL) {
1008 C_LOGE("Unknown param app type.");
1009 return PC_ERR_INVALID_PARAM;
1012 if (!smack_label_is_valid(pkg_id)) {
1013 C_LOGE("Invalid param app_id.");
1014 return PC_ERR_INVALID_PARAM;
1017 if (permission_name == NULL) {
1018 C_LOGE("Invalid param permission_name (NULL).");
1019 return PC_ERR_INVALID_PARAM;
1022 if (is_enabled == NULL) {
1023 C_LOGE("Invalid param is_enabled (NULL).");
1024 return PC_ERR_INVALID_PARAM;
1027 return rdb_app_has_permission(pkg_id, app_group, permission_name, is_enabled);
1030 API int perm_app_get_permissions(const char *pkg_id, app_type_t app_type, char ***ppp_perm_list)
1032 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d", __func__, pkg_id,
1035 const char *app_group = app_type_group_name(app_type);
1038 if (ppp_perm_list == NULL) {
1039 C_LOGE("Invalid param ppp_perm_list (NULL).");
1040 return PC_ERR_INVALID_PARAM;
1042 // Set the given pointer to NULL in case of future failure.
1043 *ppp_perm_list = NULL;
1045 if (app_group == NULL) {
1046 C_LOGE("Unknown param app type.");
1047 return PC_ERR_INVALID_PARAM;
1050 if (!smack_label_is_valid(pkg_id)) {
1051 C_LOGE("Invalid param app_id.");
1052 return PC_ERR_INVALID_PARAM;
1055 ret = rdb_app_get_permissions(pkg_id, app_group, ppp_perm_list);
1056 if (ret != PC_OPERATION_SUCCESS) {
1057 C_LOGE("RDB rdb_app_get_permissions failed with: %d", ret);
1061 return PC_OPERATION_SUCCESS;
1064 API int app_label_dir(const char* label, const char* path)//deprecated
1066 SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s",
1067 __func__, label, path);
1069 int ret = PC_OPERATION_SUCCESS;
1072 C_LOGE("Invalid argument path (NULL).");
1073 return PC_ERR_INVALID_PARAM;
1076 if (!smack_label_is_valid(label)) {
1077 C_LOGE("Invalid param label.");
1078 return PC_ERR_INVALID_PARAM;
1081 //setting access label on everything in given directory and below
1082 ret = dir_set_smack_r(path, label, SMACK_LABEL_ACCESS, &label_all);
1083 if (PC_OPERATION_SUCCESS != ret)
1085 C_LOGE("dir_set_smack_r failed.");
1089 //setting execute label for everything with permission to execute
1090 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_execs);
1091 if (PC_OPERATION_SUCCESS != ret)
1093 C_LOGE("dir_set_smack_r failed.");
1097 //setting execute label for everything with permission to execute
1098 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_links_to_execs);
1103 API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
1105 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
1106 __func__, app_label, shared_label, path);
1110 C_LOGE("Invalid param path.");
1111 return PC_ERR_INVALID_PARAM;
1114 if(!smack_label_is_valid(app_label)) {
1115 C_LOGE("Invalid param app_label");
1116 return PC_ERR_INVALID_PARAM;
1119 if(!smack_label_is_valid(shared_label)) {
1120 C_LOGE("Invalid param shared_label");
1121 return PC_ERR_INVALID_PARAM;
1124 if (strcmp(app_label, shared_label) == 0) {
1125 C_LOGE("app_label equals shared_label");
1126 return PC_ERR_INVALID_PARAM;
1129 //setting label on everything in given directory and below
1130 ret = dir_set_smack_r(path, shared_label, SMACK_LABEL_ACCESS, label_all);
1131 if(ret != PC_OPERATION_SUCCESS){
1132 C_LOGE("dir_set_smack_r failed.");
1136 //setting transmute on dir
1137 ret = dir_set_smack_r(path, "1", SMACK_LABEL_TRANSMUTE, label_dirs);
1138 if (ret != PC_OPERATION_SUCCESS) {
1139 C_LOGE("dir_set_smack_r failed");
1143 return PC_OPERATION_SUCCESS;
1146 API int add_shared_dir_readers(const char* shared_label UNUSED, const char** app_list UNUSED)//deprecated
1148 SECURE_C_LOGD("Entering function: %s. Params: shared_label=%s",
1149 __func__, shared_label);
1151 C_LOGE("add_shared_dir_readers is deprecated and unimplemented!");
1153 // TODO: This function is not implemented with RDB.
1154 return PC_ERR_INVALID_OPERATION;
1157 static char* smack_label_for_path(const char *app_id, const char *path)
1159 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, path=%s",
1160 __func__, app_id, path);
1162 char *salt AUTO_FREE;
1166 /* Prefix $1$ causes crypt() to use MD5 function */
1167 if (-1 == asprintf(&salt, "$1$%s", app_id)) {
1168 C_LOGE("asprintf failed");
1172 label = crypt(path, salt);
1173 if (label == NULL) {
1174 C_LOGE("crypt failed");
1178 /* crypt() output may contain slash character,
1179 * which is not legal in Smack labels */
1180 for (x = label; *x; ++x) {
1188 /* FIXME: remove this pragma once deprecated API is deleted */
1189 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1190 static int perm_app_setup_path_internal(const char* pkg_id, const char* path, app_path_type_t app_path_type, va_list ap)
1192 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1193 __func__, pkg_id, path, app_path_type);
1196 C_LOGE("Invalid argument path.");
1197 return PC_ERR_INVALID_PARAM;
1200 if (!smack_label_is_valid(pkg_id)) {
1201 C_LOGE("Invalid pkg_id.");
1202 SECURE_C_LOGE("Invalid pkg_id %s", pkg_id);
1203 return PC_ERR_INVALID_PARAM;
1206 switch (app_path_type) {
1207 case APP_PATH_PRIVATE:
1208 C_LOGD("app_path_type is APP_PATH_PRIVATE.");
1209 return app_label_dir(pkg_id, path);
1211 case APP_PATH_GROUP: {
1212 C_LOGD("app_path_type is APP_PATH_GROUP.");
1214 const char *shared_label;
1216 shared_label = va_arg(ap, const char *);
1218 if (!smack_label_is_valid(shared_label)) {
1219 C_LOGE("Invalid shared_label.");
1220 return PC_ERR_INVALID_PARAM;
1223 if (strcmp(pkg_id, shared_label) == 0) {
1224 C_LOGE("pkg_id equals shared_label.");
1225 return PC_ERR_INVALID_PARAM;
1228 ret = app_label_shared_dir(pkg_id, shared_label, path);
1229 if (ret != PC_OPERATION_SUCCESS) {
1230 C_LOGE("app_label_shared_dir failed: %d", ret);
1234 // Add the path to the database:
1235 ret = rdb_add_path(pkg_id, shared_label, path, "rwxatl", "-", "GROUP_PATH");
1236 if (ret != PC_OPERATION_SUCCESS) {
1237 C_LOGE("RDB rdb_add_path failed with: %d", ret);
1241 return PC_OPERATION_SUCCESS;
1244 case APP_PATH_PUBLIC: {
1245 C_LOGD("app_path_type is APP_PATH_PUBLIC.");
1246 char **app_ids AUTO_FREE;
1250 C_LOGD("New public RO path %s", path);
1253 label = smack_label_for_path(pkg_id, path);
1254 if (label == NULL) {
1255 C_LOGE("smack_label_for_path failed.");
1256 return PC_ERR_INVALID_OPERATION;
1258 C_LOGD("Generated label '%s' for public RO path %s", label, path);
1260 ret = app_label_shared_dir(pkg_id, label, path);
1261 if (ret != PC_OPERATION_SUCCESS) {
1262 C_LOGE("app_label_shared_dir failed.");
1266 // Add the path to the database:
1267 ret = rdb_add_path(pkg_id, label, path, "rwxatl", "-", "PUBLIC_PATH");
1268 if (ret != PC_OPERATION_SUCCESS) {
1269 C_LOGE("RDB rdb_add_path failed with: %d", ret);
1273 return PC_OPERATION_SUCCESS;
1276 case APP_PATH_SETTINGS: {
1277 C_LOGD("app_path_type is APP_PATH_SETTINGS.");
1278 char **app_ids AUTO_FREE;
1283 label = smack_label_for_path(pkg_id, path);
1284 if (label == NULL) {
1285 C_LOGE("smack_label_for_path failed.");
1286 return PC_ERR_INVALID_OPERATION;
1288 C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
1290 /*set id for path and all subfolders*/
1291 ret = app_label_shared_dir(pkg_id, label, path);
1292 if (ret != PC_OPERATION_SUCCESS) {
1293 C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
1297 // Add the path to the database:
1298 ret = rdb_add_path(pkg_id, label, path, "rwxatl", "-", "SETTINGS_PATH");
1299 if (ret != PC_OPERATION_SUCCESS) {
1300 C_LOGE("RDB rdb_add_path failed with: %d", ret);
1304 return PC_OPERATION_SUCCESS;
1307 case PERM_APP_PATH_NPRUNTIME: {
1308 C_LOGD("app_path_type is PERM_APP_PATH_NPRUNTIME.");
1309 char label[SMACK_LABEL_LEN + 1];
1313 if ((strlen(pkg_id) + strlen(".npruntime")) > SMACK_LABEL_LEN) {
1314 C_LOGE("cannot create npruntime label, pkg_id is too long.");
1315 return PC_ERR_INVALID_PARAM;
1317 ret = sprintf(label, "%s.npruntime", pkg_id);
1319 C_LOGE("creating npruntime label failed.");
1320 return PC_ERR_INVALID_OPERATION;
1322 C_LOGD("Generated npruntime label '%s' for path %s", label, path);
1324 // Label executable/symlink
1325 ret = set_exec_label(label, path);
1326 if (ret != PC_OPERATION_SUCCESS) {
1327 C_LOGE("cannot set executable label '%s' for path %s.", label, path);
1331 // Add the path to the database:
1332 ret = rdb_add_path(pkg_id, label, path, "rw", "rxat", "NPRUNTIME_PATH");
1333 if (ret != PC_OPERATION_SUCCESS) {
1334 C_LOGE("RDB rdb_add_path failed with: %d", ret);
1338 return PC_OPERATION_SUCCESS;
1341 case APP_PATH_ANY_LABEL: {
1342 C_LOGD("app_path_type is APP_PATH_ANY_LABEL.");
1343 const char *label = NULL;
1344 label = va_arg(ap, const char *);
1345 return app_label_dir(label, path);
1349 C_LOGE("app_path_type is invalid.");
1350 return PC_ERR_INVALID_PARAM;
1353 return PC_OPERATION_SUCCESS;
1355 /* FIXME: remove this pragma once deprecated API is deleted */
1356 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
1358 API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)//deprecated
1360 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1361 __func__, pkg_id, path, app_path_type);
1365 va_start( ap, app_path_type );
1366 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
1372 API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
1374 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1375 __func__, pkg_id, path, app_path_type);
1379 va_start( ap, app_path_type );
1380 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
1385 API int perm_app_get_paths(const char* pkg_id, app_path_type_t app_path_type, char*** ppp_paths)
1387 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_path_type=%d", __func__,
1388 pkg_id, app_path_type);
1390 const char *path_type_name = app_path_type_name(app_path_type);
1393 if (ppp_paths == NULL) {
1394 C_LOGE("Invalid param ppp_paths (NULL).");
1395 return PC_ERR_INVALID_PARAM;
1397 // Set the given pointer to NULL in case of future failure.
1400 if (path_type_name == NULL) {
1401 C_LOGE("Unknown or invalid param app_path_type.");
1402 return PC_ERR_INVALID_PARAM;
1405 if (!smack_label_is_valid(pkg_id)) {
1406 C_LOGE("Invalid param app_id.");
1407 return PC_ERR_INVALID_PARAM;
1410 ret = rdb_get_app_paths(pkg_id, path_type_name, ppp_paths);
1411 if (ret != PC_OPERATION_SUCCESS) {
1412 C_LOGE("RDB rdb_app_get_paths failed with: %d", ret);
1416 return PC_OPERATION_SUCCESS;
1419 API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
1421 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
1422 __func__, pkg_id1, pkg_id2);
1424 return perm_app_add_friend(pkg_id1, pkg_id2);
1427 API int perm_app_add_friend(const char* pkg_id1 UNUSED, const char* pkg_id2 UNUSED)
1429 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
1430 __func__, pkg_id1, pkg_id2);
1432 C_LOGE("app_register_av is deprecated and unimplemented!");
1434 // TODO: This function is not implemented with RDB.
1435 return PC_ERR_INVALID_OPERATION;
1438 API int app_install(const char* pkg_id)//deprecated
1440 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1443 return perm_app_install(pkg_id);
1446 API int perm_app_install(const char* pkg_id)
1448 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1452 char* smack_path AUTO_FREE;
1453 struct smack_accesses *smack AUTO_SMACK_FREE;
1455 if (!smack_label_is_valid(pkg_id)) {
1456 C_LOGE("Invalid param pkg_id.");
1457 return PC_ERR_INVALID_PARAM;
1460 // Add application to the database:
1461 ret = rdb_add_application(pkg_id);
1462 if (ret != PC_OPERATION_SUCCESS) {
1463 C_LOGE("RDB rdb_add_application failed with: %d", ret);
1467 return PC_OPERATION_SUCCESS;
1470 API int app_uninstall(const char* pkg_id)//deprecated
1472 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1475 return perm_app_uninstall(pkg_id);
1478 API int perm_app_uninstall(const char* pkg_id)
1480 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1481 char* smack_path AUTO_FREE;
1484 if (!smack_label_is_valid(pkg_id)) {
1485 C_LOGE("Invalid param pkg_id.");
1486 return PC_ERR_INVALID_PARAM;
1489 // Remove application from the database
1490 ret = rdb_remove_application(pkg_id);
1491 if (ret != PC_OPERATION_SUCCESS) {
1492 C_LOGE("RDB rdb_remove_application failed with: %d", ret);
1496 return PC_OPERATION_SUCCESS;
1499 static int save_gids(FILE* file, const gid_t* list_of_db_gids, size_t list_size) {
1501 SECURE_C_LOGD("Entering function: %s.", __func__);
1502 int ret = PC_OPERATION_SUCCESS;
1507 C_LOGE("Unable to create file. Error: %s", strerror(errno));
1508 return PC_ERR_FILE_OPERATION; // TODO remove smack accesses?
1511 if(-1 == fchmod(fileno(file), 0644)) {
1512 C_LOGE("Unable to chmod file. Error: %s", strerror(errno));
1513 return PC_ERR_FILE_OPERATION;
1516 for (i = 0; i < list_size ; ++i) {
1517 written = fprintf(file, "%u\n", list_of_db_gids[i]);
1519 C_LOGE("fprintf failed for file. Error: %s", strerror(errno));
1520 ret = PC_ERR_FILE_OPERATION;
1527 API int add_api_feature(app_type_t app_type,
1528 const char* api_feature_name,
1529 const char** smack_rules,
1530 const gid_t* list_of_db_gids,
1531 size_t list_size)//deprecated
1533 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
1534 __func__, app_type, api_feature_name);
1536 return perm_add_api_feature(app_type, api_feature_name, smack_rules, list_of_db_gids, list_size);
1539 API int perm_add_api_feature(app_type_t app_type,
1540 const char* api_feature_name,
1541 const char** smack_rules,
1542 const gid_t* list_of_db_gids,
1544 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
1545 __func__, app_type, api_feature_name);
1547 int ret = PC_OPERATION_SUCCESS;
1548 char* smack_file AUTO_FREE;
1549 char* dac_file AUTO_FREE;
1550 char * base_api_feature_name AUTO_FREE;
1552 // struct smack_accesses* accesses = NULL;
1553 const char *s_type_name = app_type_name(app_type);
1555 // Check input values
1556 if (s_type_name == NULL || !strcmp(s_type_name, "")) {
1557 C_LOGE("Unknown api type");
1558 return PC_ERR_INVALID_PARAM;
1561 if (api_feature_name == NULL || strlen(api_feature_name) == 0) {
1562 C_LOGE("Api feature name is empty.");
1563 return PC_ERR_INVALID_PARAM;
1566 if (smack_rules && ((ret = validate_all_rules(smack_rules) ) != PC_OPERATION_SUCCESS) ) {
1567 C_LOGE("Error in rules list.");
1571 // check .dac existence only if gids are supported
1572 if (list_of_db_gids && list_size > 0) {
1573 // get feature DAC file name
1574 ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac", 0);
1575 if (ret != PC_OPERATION_SUCCESS || !dac_file ) {
1576 C_LOGE("perm_file_path failed.");
1583 // go through gid list
1584 if (ret == PC_OPERATION_SUCCESS && list_of_db_gids && list_size > 0) {
1586 SECURE_C_LOGD("Opening file %s.", dac_file);
1587 file = fopen(dac_file, "w+");
1588 ret = save_gids(file, list_of_db_gids, list_size);
1589 if(file) fclose(file);
1592 // remove file in case of failure
1593 if (ret != PC_OPERATION_SUCCESS && dac_file) {
1597 ret = base_name_from_perm(api_feature_name, &base_api_feature_name);
1598 if (ret != PC_OPERATION_SUCCESS){
1599 C_LOGE("Error during creating base name: ", ret);
1603 // Save api feature to the database.
1604 ret = rdb_add_permission_rules(base_api_feature_name, s_type_name, smack_rules);
1605 if (ret != PC_OPERATION_SUCCESS) {
1606 C_LOGE("RDB rdb_add_permission_rules failed with: %d", ret);
1614 * This function is marked as deprecated and will be removed
1616 API int app_register_av(const char* app_av_id UNUSED)//deprecated
1618 SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s",
1619 __func__, app_av_id);
1621 C_LOGE("app_register_av is deprecated and unimplemented!");
1623 // TODO: This function is not implemented with RDB.
1624 return PC_ERR_INVALID_OPERATION;
1627 API int perm_add_additional_rules(const char** smack_rules){
1628 SECURE_C_LOGD("Entering function: %s.", __func__);
1631 C_LOGE("smack_rules is NULL");
1632 return PC_ERR_INVALID_PARAM;
1635 ret = rdb_add_additional_rules(smack_rules);
1636 if (ret != PC_OPERATION_SUCCESS) {
1637 C_LOGE("RDB rdb_add_additional_rules failed with: %d", ret);
1641 return PC_OPERATION_SUCCESS;
1644 API const char* perm_strerror(int errnum)
1647 case PC_OPERATION_SUCCESS:
1649 case PC_ERR_FILE_OPERATION:
1650 return "File operation error";
1651 case PC_ERR_MEM_OPERATION:
1652 return "Memory operation error";
1653 case PC_ERR_NOT_PERMITTED:
1654 return "Operation not permitted";
1655 case PC_ERR_INVALID_PARAM:
1656 return "Invalid parameter";
1657 case PC_ERR_INVALID_OPERATION:
1658 return "Invalid operation";
1659 case PC_ERR_DB_OPERATION:
1660 return "Database operation error";
1661 case PC_ERR_DB_LABEL_TAKEN:
1662 return "Label taken by another application";
1663 case PC_ERR_DB_QUERY_PREP:
1664 return "Query failure during preparation";
1665 case PC_ERR_DB_QUERY_BIND:
1666 return "Query failure during binding";
1667 case PC_ERR_DB_QUERY_STEP:
1668 return "Query failure during stepping";
1669 case PC_ERR_DB_CONNECTION:
1670 return "Cannot establish a connection";
1671 case PC_ERR_DB_NO_SUCH_APP:
1672 return "No such application";
1673 case PC_ERR_DB_PERM_FORBIDDEN:
1674 return "Duplicate permission";
1676 return "Unknown error";