Remove unnecessary defines.
[platform/core/security/libprivilege-control.git] / src / privilege-control.c
index 3a5a941..3cefcc5 100644 (file)
@@ -37,6 +37,7 @@
 #include <sys/file.h>
 #include <sys/smack.h>
 #include <linux/capability.h>
+#include <linux/xattr.h>
 #include <sys/capability.h>
 #include <sys/mman.h>
 #include <stdbool.h>
 #define APP_HOME_DIR   TOSTRING(HOMEDIR) "/app"
 #define DEV_HOME_DIR   TOSTRING(HOMEDIR) "/developer"
 
-#define APP_GROUP_PATH TOSTRING(SHAREDIR) "/app_group_list"
-#define DEV_GROUP_PATH TOSTRING(SHAREDIR) "/dev_group_list"
-
-#define SMACK_SRC_FILE_SUFFIX   "_src_file"
-#define SMACK_SRC_DIR_SUFFIX    "_src_dir"
-#define SMACK_DATA_SUFFIX       "_data"
-#define WRT_BASE_DEVCAP         "WRT"
-#define WRT_CLIENT_PATH         "/usr/bin/wrt-client"
-#define ACC_LEN                 6
-#define TIZEN_PRIVILEGE_ANTIVIRUS  "http://tizen.org/privilege/antivirus"
-#define TIZEN_PRIVILEGE_APPSETTING "http://tizen.org/privilege/appsetting"
-#define PATH_RULES_PUBLIC_RO       "PATH_RULES_PUBLIC_RO.smack"
-#define PATH_RULES_GROUP_RW        "PATH_RULES_GROUP_RW.smack"
+/* Macro defined below is used to label links to executables */
+#define XATTR_NAME_TIZENEXEC XATTR_SECURITY_PREFIX "TIZEN_EXEC_LABEL"
 
 typedef struct {
        char user_name[10];
        int uid;
        int gid;
        char home_dir[64];
-       char group_list[64];
 } new_user;
 
 /**
@@ -109,8 +98,20 @@ API int perm_end(void)
 {
        SECURE_C_LOGD("Entering function: %s.", __func__);
 
-       rdb_modification_finish();
-       sync();
+       return rdb_modification_finish();
+}
+
+API int perm_rollback(void)
+{
+       SECURE_C_LOGD("Entering function: %s.", __func__);
+
+       int ret = rdb_modification_rollback();
+
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("RDB %s failed with: %d", __func__, ret);
+               return ret;
+       }
+
        return PC_OPERATION_SUCCESS;
 }
 
@@ -129,135 +130,36 @@ API int control_privilege(void)//deprecated
        }
 }
 
-/**
- * TODO: this function should be moved to libsmack in open-source.
- */
-API int get_smack_label_from_process(pid_t pid, char *smack_label)
-{
-       SECURE_C_LOGD("Entering function: %s. Params: pid=%i", __func__, pid);
-
-       int ret;
-       int fd AUTO_CLOSE;
-       int PATH_MAX_LEN = 64;
-       char path[PATH_MAX_LEN + 1];
-
-       if (pid < 0) {
-               C_LOGE("invalid param pid.");
-               ret = PC_ERR_INVALID_PARAM;
-               goto out;
-       }
-
-       if(smack_label == NULL) {
-               C_LOGE("Invalid param smack_label (NULL).");
-               ret = PC_ERR_INVALID_PARAM;
-               goto out;
-       }
-
-       bzero(smack_label, SMACK_LABEL_LEN + 1);
-       if (!have_smack()) { // If no smack just return success with empty label
-               C_LOGD("No SMACK. Returning empty label");
-               ret = PC_OPERATION_SUCCESS;
-               goto out;
-       }
-
-       bzero(path, PATH_MAX_LEN + 1);
-       snprintf(path, PATH_MAX_LEN, "/proc/%d/attr/current", pid);
-       fd = open(path, O_RDONLY);
-       if (fd < 0) {
-               SECURE_C_LOGE("Cannot open file %s (errno: %s)", path, strerror(errno));
-               ret = PC_ERR_FILE_OPERATION;
-               goto out;
-       }
-
-       ret = read(fd, smack_label, SMACK_LABEL_LEN);
-       if (ret < 0) {
-               SECURE_C_LOGE("Cannot read from file %s", path);
-               ret = PC_ERR_FILE_OPERATION;
-               goto out;
-       }
-
-       SECURE_C_LOGD("smack_label=%s", smack_label);
-
-       ret = PC_OPERATION_SUCCESS;
-
-out:
-       return ret;
-}
-
-API int smack_pid_have_access(pid_t pid,
-                                                               const char* object,
-                                                               const char *access_type)
+static int get_user_groups(uid_t user_id, int *nbgroup, gid_t **groups_list)
 {
-       SECURE_C_LOGD("Entering function: %s. Params: pid=%i, object=%s, access_type=%s",
-                               __func__, pid, object, access_type);
-
-       int ret;
-       char pid_subject_label[SMACK_LABEL_LEN + 1];
-       cap_t cap;
-       cap_flag_value_t cap_v;
-
-       if (!have_smack()) {
-               C_LOGD("No SMACK. Return access granted");
-               return 1;
-       }
-
-       if (pid < 0) {
-               C_LOGE("Invalid pid.");
-               return -1;
-       }
-
-       if(object == NULL) {
-               C_LOGE("Invalid object param.");
-               return -1;
-       }
-
-       if(access_type == NULL) {
-               C_LOGE("Invalid access_type param");
-               return -1;
-       }
-
-       //get SMACK label of process
-       ret = get_smack_label_from_process(pid, pid_subject_label);
-       if (PC_OPERATION_SUCCESS != ret) {
-               SECURE_C_LOGE("get_smack_label_from_process %d failed: %d", pid, ret);
-               return -1;
-       }
-       SECURE_C_LOGD("pid %d has label: %s", pid, pid_subject_label);
-
-       // do not call smack_have_access() if label is empty
-       if (pid_subject_label[0] != '\0') {
-               ret = smack_have_access(pid_subject_label, object, access_type);
-               if ( -1 == ret) {
-                       C_LOGE("smack_have_access failed.");
-                       return -1;
-               }
-               if ( 1 == ret ) { // smack_have_access return 1 (access granted)
-                       C_LOGD("smack_have_access returned 1 (access granted)");
-                       return 1;
-               }
-       }
+       gid_t *groups = NULL;
+       struct passwd * pw;
+       C_LOGD("Enter function: %s", __func__);
 
-       // smack_have_access returned 0 (access denied). Now CAP_MAC_OVERRIDE should be checked
-       C_LOGD("smack_have_access returned 0 (access denied)");
-       cap = cap_get_pid(pid);
-       if (cap == NULL) {
-               C_LOGE("cap_get_pid failed");
-               return -1;
-       }
-       ret = cap_get_flag(cap, CAP_MAC_OVERRIDE, CAP_EFFECTIVE, &cap_v);
-       if (0 != ret) {
-               C_LOGE("cap_get_flag failed");
-               return -1;
+       if ((!groups_list) || (!nbgroup))
+               return PC_ERR_INVALID_OPERATION;
+       pw = getpwuid(user_id);
+       if(!pw) {
+               C_LOGE("getgrouplist fails : Invalid User ID %d",user_id);
+               return PC_ERR_INVALID_OPERATION;
        }
+       *nbgroup = 0;
+       //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.
+       if (getgrouplist(pw->pw_name,  pw->pw_gid, groups, nbgroup) != -1)
+               return PC_ERR_INVALID_OPERATION;
 
-       if (cap_v == CAP_SET) {
-               C_LOGD("pid %d has CAP_MAC_OVERRIDE", pid);
-               return 1;
-
-       } else {
-               C_LOGD("pid %d doesn't have CAP_MAC_OVERRIDE", pid);
-               return 0;
+       C_LOGD("getgrouplist %s user is member of %d groups ",pw->pw_name,*nbgroup);
+       groups = malloc(*nbgroup * sizeof (gid_t));
+       if (!groups)
+               return PC_ERR_INVALID_OPERATION;
+       //Second call is done with the suitable ngroup value and structure groups allocated.
+       if (getgrouplist(pw->pw_name,  pw->pw_gid, groups, nbgroup) == -1) {
+               free(groups);
+               C_LOGE("getgrouplist fails %d",nbgroup);
+               return PC_ERR_INVALID_OPERATION;
        }
+       *groups_list = groups;
+       return  PC_OPERATION_SUCCESS;
 }
 
 static int set_dac(const char *smack_label, const char *pkg_name)
@@ -265,11 +167,8 @@ static int set_dac(const char *smack_label, const char *pkg_name)
        SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s, pkg_name=%s",
                                __func__, smack_label, pkg_name);
 
-       FILE* fp_group = NULL;  // /etc/group
        uid_t t_uid = -1;               // uid of current process
        gid_t *glist = NULL;    // group list
-       gid_t temp_gid = -1;    // for group list
-       char buf[10] = {0, };           // contents in group_list file
        int glist_cnt = 0;              // for group list
        int result;
        int i;
@@ -282,7 +181,6 @@ static int set_dac(const char *smack_label, const char *pkg_name)
        C_LOGD("Initialize user structure");
        memset(usr.user_name, 0x00, 10);
        memset(usr.home_dir, 0x00, 64);
-       memset(usr.group_list, 0x00, 64);
        usr.uid = -1;
        usr.gid = -1;
 
@@ -297,7 +195,6 @@ static int set_dac(const char *smack_label, const char *pkg_name)
                        usr.uid = DEVELOPER_UID;
                        usr.gid = DEVELOPER_GID;
                        strncpy(usr.home_dir, DEV_HOME_DIR, sizeof(usr.home_dir));
-                       strncpy(usr.group_list, DEV_GROUP_PATH, sizeof(usr.group_list));
                }
                else
                {
@@ -305,46 +202,16 @@ static int set_dac(const char *smack_label, const char *pkg_name)
                        usr.uid = APP_UID;
                        usr.gid = APP_GID;
                        strncpy(usr.home_dir, APP_HOME_DIR, sizeof(usr.home_dir));
-                       strncpy(usr.group_list, APP_GROUP_PATH, sizeof(usr.group_list));
                }
 
                /*
                 * get group information
                 */
-               C_LOGD("Get group information");
-               SECURE_C_LOGD("Opening file %s.", usr.group_list);
-               if(!(fp_group = fopen(usr.group_list, "r")))
-               {
-                       C_LOGE("fopen failed.");
+               C_LOGD("get group information");
+               if (get_user_groups(usr.uid, &glist_cnt, &glist)) {
                        result = PC_ERR_FILE_OPERATION; // return -1
                        goto error;
                }
-
-               while(fgets(buf, 10, fp_group) != NULL)
-               {
-                       errno = 0;
-                       temp_gid = strtoul(buf, 0, 10);
-                       if(errno != 0)  // error occured during strtoul()
-                       {
-                               C_LOGE("Cannot change string to integer: %s", buf);
-                               result = PC_ERR_INVALID_OPERATION;
-                               goto error;
-                       }
-
-                       glist = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + 1));
-                       if(!glist)
-                       {
-                               result = PC_ERR_MEM_OPERATION;  // return -2
-                               C_LOGE("Cannot allocate memory");
-                               goto error;
-                       }
-                       glist[glist_cnt] = temp_gid;
-                       glist_cnt++;
-               }
-               fclose(fp_group);
-               fp_group = NULL;
-
-               if(NULL != smack_label)
                {
                        gid_t *glist_new;
                        int i, cnt;
@@ -429,8 +296,6 @@ static int set_dac(const char *smack_label, const char *pkg_name)
        result = PC_OPERATION_SUCCESS;
 
 error:
-       if(fp_group != NULL)
-               fclose(fp_group);
        if(glist != NULL)
                free(glist);
        free(additional_gids);
@@ -445,26 +310,50 @@ error:
  * @param path file path to take label from
  * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
  */
-static int get_smack_from_binary(char **smack_label, const char* path, app_type_t type)
+static int get_smack_from_binary(char **smack_label, const char* path)
 {
-       SECURE_C_LOGD("Entering function: %s. Params: path=%s, type=%d",
-                               __func__, path, type);
+       SECURE_C_LOGD("Entering function: %s. Params: path=%s", __func__, path);
+       char value[SMACK_LABEL_LEN + 1];
        int ret;
 
+       /* First try: check SMACKEXEC label on binary */
+       ret = getxattr(path, XATTR_NAME_SMACKEXEC, value, SMACK_LABEL_LEN + 1);
+       if (ret > 0)
+               goto finalize;
+       if (errno != ENODATA)
+               goto error;
+
+       /* Second try: check TIZENEXEC label on binary */
+       ret = getxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
+       if (ret > 0)
+               goto finalize;
+       if (errno != ENODATA)
+               goto error;
+
+       /* Third try: check TIZENEXEC label on symbolic link */
+       ret = lgetxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
+       if (ret > 0)
+               goto finalize;
+       if (errno != ENODATA)
+               goto error;
+
+       /* None of labels found  return NULL*/
        *smack_label = NULL;
-       if (type == PERM_APP_TYPE_WGT
-       || type == PERM_APP_TYPE_WGT_PARTNER
-       || type == PERM_APP_TYPE_WGT_PLATFORM) {
-               ret = smack_lgetlabel(path, smack_label, SMACK_LABEL_EXEC);
-       } else {
-               ret = smack_getlabel(path, smack_label, SMACK_LABEL_EXEC);
-       }
-       if (ret != 0) {
-               C_LOGE("Getting exec label from file %s failed", path);
-               return PC_ERR_INVALID_OPERATION;
-       }
+       return PC_OPERATION_SUCCESS;
 
+finalize:
+       /* Success! */
+       value[ret] = '\0';  /* because getxattr does not add 0 at the end! */
+       *smack_label = strdup(value);
+       if (*smack_label == NULL) {
+               C_LOGE("Cannot allocate memory for smack_label");
+               return PC_ERR_MEM_OPERATION;
+       }
        return PC_OPERATION_SUCCESS;
+
+error:
+       C_LOGE("Getting exec label from file %s failed", path);
+       return PC_ERR_INVALID_OPERATION;
 }
 
 /**
@@ -498,77 +387,6 @@ static int set_smack_for_self (char *smack_label)
        return ret;
 }
 
-static int is_widget(const char* path)
-{
-       SECURE_C_LOGD("Entering function: %s. Params: path=%s",
-                               __func__, path);
-       char buf[sizeof(WRT_CLIENT_PATH)];
-       int ret;
-
-       ret = readlink(path, buf, sizeof(WRT_CLIENT_PATH));
-       if (ret == -1)
-               C_LOGD("readlink(%s) returned error: %s. Assuming that app is not a widget", path, strerror(errno));
-       else if (ret == sizeof(WRT_CLIENT_PATH))
-               C_LOGD("%s is not a widget", path);
-       if (ret == -1 || ret == sizeof(WRT_CLIENT_PATH))
-               return 0;
-       buf[ret] = '\0';
-       C_LOGD("buf=%s", buf);
-
-       ret = !strcmp(WRT_CLIENT_PATH, buf);
-       C_LOGD("%s is %s widget", path, ret ? "a" : "not a");
-       return (ret);
-}
-
-/**
- * Partially verify, that the type given for app is correct.
- * This function will use some heuristics to check whether the app type is right.
- * It is intended for security hardening to catch privilege setting for the
- * app type not corresponding to the actual binary.
- * Beware - when it detects an anomaly, the whole process will be terminated.
- *
- * @param type claimed application type
- * @param path file path to executable
- * @return return void on success, terminate the process on error
- */
-static app_type_t verify_app_type(const char* type, const char* path)
-{
-       SECURE_C_LOGD("Entering function: %s. Params: type=%s, path=%s",
-                               __func__, type, path);
-
-       /* TODO: this should actually be treated as error, but until the old
-        * set_privilege API is removed, it must be ignored */
-       if (path == NULL) {
-               C_LOGD("PKG_TYPE_OTHER");
-               return APP_TYPE_OTHER; /* good */
-       }
-
-       if (is_widget(path)) {
-               if (!strcmp(type, "wgt")) {
-                       C_LOGD("PKG_TYPE_WGT");
-                       return PERM_APP_TYPE_WGT; /* good */
-               } else if (!strcmp(type, "wgt_partner")) {
-                       C_LOGD("PKG_TYPE_WGT_PARTNER");
-                       return PERM_APP_TYPE_WGT_PARTNER; /* good */
-               } else if (!strcmp(type, "wgt_platform")) {
-                       C_LOGD("PKG_TYPE_WGT_PLATFORM");
-                       return PERM_APP_TYPE_WGT_PLATFORM; /* good */
-               }
-
-       } else {
-               if (type == NULL || (strcmp(type, "wgt")
-                               && strcmp(type, "wgt_partner")
-                               && strcmp(type, "wgt_platform"))){
-                       C_LOGD("PKG_TYPE_OTHER");
-                       return PERM_APP_TYPE_OTHER; /* good */
-               }
-       }
-
-       /* bad */
-       C_LOGE("EXIT_FAILURE");
-       exit(EXIT_FAILURE);
-}
-
 API int set_app_privilege(const char* name, const char* type, const char* path)//deprecated
 {
        SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
@@ -577,7 +395,7 @@ API int set_app_privilege(const char* name, const char* type, const char* path)/
        return perm_app_set_privilege(name, type, path);
 }
 
-API int perm_app_set_privilege(const char* name, const char* type, const char* path)
+API int perm_app_set_privilege(const char* name, const char* type UNUSED, const char* path)
 {
        SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
                                __func__, name, type, path);
@@ -592,7 +410,7 @@ API int perm_app_set_privilege(const char* name, const char* type, const char* p
        }
 
        if (path != NULL && have_smack()) {
-               ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
+               ret = get_smack_from_binary(&smack_label, path);
                if (ret != PC_OPERATION_SUCCESS)
                        return ret;
 
@@ -602,7 +420,7 @@ API int perm_app_set_privilege(const char* name, const char* type, const char* p
        }
 
        if (path != NULL && !have_smack()) {
-               ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
+               ret = get_smack_from_binary(&smack_label, path);
                if (ret != PC_OPERATION_SUCCESS)
                        return ret;
        }
@@ -753,16 +571,22 @@ static int label_links_to_execs(const FTSENT* ftsent)
 }
 
 static int dir_set_smack_r(const char *path, const char* label,
-               enum smack_label_type type, label_decision_fn fn)
+                          const char *xattr_name, label_decision_fn fn)
 {
-       SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, type=%d",
-                               __func__, path, label, type);
+       SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, xattr_name=%s",
+                               __func__, path, label, xattr_name);
 
        const char* path_argv[] = {path, NULL};
        FTS *fts AUTO_FTS_CLOSE;
        FTSENT *ftsent;
        int ret;
 
+       int len = strnlen(label, SMACK_LABEL_LEN + 1);
+       if (len > SMACK_LABEL_LEN) {
+               C_LOGE("parameter \"label\" is to long.");
+               return PC_ERR_INVALID_PARAM;
+       }
+
        fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
        if (fts == NULL) {
                C_LOGE("fts_open failed.");
@@ -783,9 +607,11 @@ static int dir_set_smack_r(const char *path, const char* label,
                }
 
                if (ret == DECISION_LABEL) {
-                       C_LOGD("smack_lsetlabel (label: %s (type: %d), path: %s)", label, type, ftsent->fts_path);
-                       if (smack_lsetlabel(ftsent->fts_path, label, type) != 0) {
-                               C_LOGE("smack_lsetlabel failed.");
+                       C_LOGD("lsetxattr (path: %s, xattr_name: %s, label: %s len: %d, 0",
+                               ftsent->fts_path, xattr_name, label, len);
+
+                       if (lsetxattr(ftsent->fts_path, xattr_name, label, len, 0) != 0) {
+                               C_LOGE("lsetxattr failed.");
                                return PC_ERR_FILE_OPERATION;
                        }
                }
@@ -831,25 +657,45 @@ API char* perm_app_id_from_socket(int sockfd)
 }
 
 
-static int app_add_permissions_internal(const char* app_id, app_type_t app_type, const char** perm_list, int permanent)
+API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
 {
-       SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, app_type=%d, permanent=%d",
-                               __func__, app_id, app_type, permanent);
+       SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
+                               __func__, app_id);
+
+       return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, true);
+}
+
+API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
+{
+       SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
+                               __func__, app_id);
+
+       return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, false);
+}
+
+API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
+{
+       SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
+                               __func__, pkg_id, app_type, persistent);
+
+       return perm_app_enable_permissions(pkg_id, app_type, perm_list, persistent);
+}
+
+API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type,
+                                   const char** perm_list, bool persistent)
+{
+       SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
+                               __func__, pkg_id, app_type, persistent);
 
        int i, ret;
-       char* smack_path AUTO_FREE;
-       char* smack_path_early AUTO_FREE;
-       int fd AUTO_CLOSE;
-       int fd_early AUTO_CLOSE;
-       struct smack_accesses *smack AUTO_SMACK_FREE;
-       struct smack_accesses *smack_early AUTO_SMACK_FREE;
-
-       if (!smack_label_is_valid(app_id)) {
+       const char *app_label AUTO_FREE;
+
+       if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param app_id.");
                return PC_ERR_INVALID_PARAM;
        }
 
-       if(perm_list == NULL) {
+       if (perm_list == NULL) {
                C_LOGE("Invalid perm_list (NULL).");
                return PC_ERR_INVALID_PARAM;
        }
@@ -859,64 +705,32 @@ static int app_add_permissions_internal(const char* app_id, app_type_t app_type,
                return PC_ERR_INVALID_PARAM;
        }
 
-       // Add permission to DAC
+       app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
+       /* Add permission to DAC */
        for (i = 0; perm_list[i] != NULL; ++i) {
-               ret = perm_to_dac(app_id, app_type, perm_list[i]);
-               if (ret != PC_OPERATION_SUCCESS){
+               ret = perm_to_dac(pkg_id, app_type, perm_list[i]);
+               if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("perm_to_dac failed");
                        return ret;
                }
        }
 
-       // Enable the permissions:
-       ret = rdb_enable_app_permissions(app_id,
-                                        app_type,
-                                        perm_list,
-                                        !((bool)permanent));
+       /* Enable the permissions: */
+       ret = rdb_enable_app_permissions(app_label, app_type, perm_list,
+                                        !((bool)persistent));
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_enable_app_permissions failed with: %d", ret);
                return ret;
        }
 
-
-       SECURE_C_LOGD("Leaving function: %s. Params: app_id=%s, app_type=%d, permanent=%d",
-                               __func__, app_id, app_type, permanent);
-
        return PC_OPERATION_SUCCESS;
 }
 
-API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
-{
-       SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
-                               __func__, app_id);
-
-       return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 1);
-}
-
-API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
-{
-       SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
-                               __func__, app_id);
-
-       return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 0);
-}
-
-API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
-{
-       SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
-                               __func__, pkg_id, app_type, persistent);
-
-       return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
-}
-
-API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)
-{
-       SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
-                               __func__, pkg_id, app_type, persistent);
-
-       return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
-}
-
 API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
@@ -925,13 +739,13 @@ API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const c
        return perm_app_disable_permissions(pkg_id, app_type, perm_list);
 }
 
-/* FIXME: this function is only a stub */
 API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
                                __func__, pkg_id, app_type);
 
        int ret;
+       const char *app_label AUTO_FREE;
        if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param app_id.");
                return PC_ERR_INVALID_PARAM;
@@ -947,7 +761,13 @@ API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, co
                return PC_ERR_INVALID_PARAM;
        }
 
-       ret = rdb_disable_app_permissions(pkg_id, app_type, perm_list);
+       app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
+       ret = rdb_disable_app_permissions(app_label, app_type, perm_list);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
                return ret;
@@ -965,18 +785,28 @@ API int app_revoke_permissions(const char* pkg_id)//deprecated
 API int perm_app_revoke_permissions(const char* pkg_id)
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
-       int ret;
+       /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+       /*int ret;
+       const char *app_label AUTO_FREE;*/
 
        if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param app_id.");
                return PC_ERR_INVALID_PARAM;
        }
 
-       ret = rdb_revoke_app_permissions(pkg_id);
+       SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
+       /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+       /*app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
+       ret = rdb_revoke_app_permissions(app_label);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
                return ret;
-       }
+       }*/
 
        return PC_OPERATION_SUCCESS;
 }
@@ -994,13 +824,20 @@ API int perm_app_reset_permissions(const char* pkg_id)
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
                                __func__, pkg_id);
        int ret;
+       const char *app_label AUTO_FREE;
 
        if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param pkg_id.");
                return PC_ERR_INVALID_PARAM;
        }
 
-       ret = rdb_reset_app_permissions(pkg_id);
+       app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
+       ret = rdb_reset_app_permissions(app_label);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
                return ret;
@@ -1027,7 +864,7 @@ API int app_label_dir(const char* label, const char* path)//deprecated
        }
 
        //setting access label on everything in given directory and below
-       ret = dir_set_smack_r(path, label, SMACK_LABEL_ACCESS, &label_all);
+       ret = dir_set_smack_r(path, label, XATTR_NAME_SMACK, &label_all);
        if (PC_OPERATION_SUCCESS != ret)
        {
                C_LOGE("dir_set_smack_r failed.");
@@ -1035,7 +872,7 @@ API int app_label_dir(const char* label, const char* path)//deprecated
        }
 
        //setting execute label for everything with permission to execute
-       ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_execs);
+       ret = dir_set_smack_r(path, label, XATTR_NAME_SMACKEXEC, &label_execs);
        if (PC_OPERATION_SUCCESS != ret)
        {
                C_LOGE("dir_set_smack_r failed.");
@@ -1043,11 +880,10 @@ API int app_label_dir(const char* label, const char* path)//deprecated
        }
 
        //setting execute label for everything with permission to execute
-       ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_links_to_execs);
+       ret = dir_set_smack_r(path, label, XATTR_NAME_TIZENEXEC, &label_links_to_execs);
        return ret;
 }
 
-
 API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
 {
        SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
@@ -1075,14 +911,14 @@ API int app_label_shared_dir(const char* app_label, const char* shared_label, co
        }
 
        //setting label on everything in given directory and below
-       ret = dir_set_smack_r(path, shared_label, SMACK_LABEL_ACCESS, label_all);
+       ret = dir_set_smack_r(path, shared_label, XATTR_NAME_SMACK, label_all);
        if(ret != PC_OPERATION_SUCCESS){
                C_LOGE("dir_set_smack_r failed.");
                return ret;
        }
 
        //setting transmute on dir
-       ret = dir_set_smack_r(path, "1", SMACK_LABEL_TRANSMUTE, label_dirs);
+       ret = dir_set_smack_r(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, label_dirs);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("dir_set_smack_r failed");
                return ret;
@@ -1139,6 +975,7 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
                                __func__, pkg_id, path, app_path_type);
+       const char *app_label AUTO_FREE;
 
        if(path == NULL) {
                C_LOGE("Invalid argument path.");
@@ -1151,12 +988,18 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
                return PC_ERR_INVALID_PARAM;
        }
 
+       app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
        switch (app_path_type) {
        case APP_PATH_PRIVATE:
                C_LOGD("app_path_type is APP_PATH_PRIVATE.");
-               return app_label_dir(pkg_id, path);
+               return app_label_dir(app_label, path);
 
-       case APP_PATH_GROUP: {
+       case APP_PATH_GROUP_RW: {
                C_LOGD("app_path_type is APP_PATH_GROUP.");
                int ret;
                const char *shared_label;
@@ -1168,19 +1011,19 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
                        return PC_ERR_INVALID_PARAM;
                }
 
-               if (strcmp(pkg_id, shared_label) == 0) {
-                       C_LOGE("pkg_id equals shared_label.");
+               if (strcmp(app_label, shared_label) == 0) {
+                       C_LOGE("app_label equals shared_label.");
                        return PC_ERR_INVALID_PARAM;
                }
 
-               ret = app_label_shared_dir(pkg_id, shared_label, path);
+               ret = app_label_shared_dir(app_label, shared_label, path);
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("app_label_shared_dir failed: %d", ret);
                        return ret;
                }
 
                // Add the path to the database:
-               ret = rdb_add_path(pkg_id, shared_label, path, "rwxatl", "GROUP_PATH");
+               ret = rdb_add_path(app_label, shared_label, path, "rwxatl", "-", "GROUP_PATH");
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("RDB rdb_add_path failed with: %d", ret);
                        return ret;
@@ -1189,30 +1032,29 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
                return PC_OPERATION_SUCCESS;
        }
 
-       case APP_PATH_PUBLIC: {
+       case APP_PATH_PUBLIC_RO: {
                C_LOGD("app_path_type is APP_PATH_PUBLIC.");
-               char **app_ids AUTO_FREE;
                const char *label;
                int ret;
 
                C_LOGD("New public RO path %s", path);
 
                // Generate label:
-               label = smack_label_for_path(pkg_id, path);
+               label = smack_label_for_path(app_label, path);
                if (label == NULL) {
                        C_LOGE("smack_label_for_path failed.");
                        return PC_ERR_INVALID_OPERATION;
                }
                C_LOGD("Generated label '%s' for public RO path %s", label, path);
 
-               ret = app_label_shared_dir(pkg_id, label, path);
+               ret = app_label_shared_dir(app_label, label, path);
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("app_label_shared_dir failed.");
                        return ret;
                }
 
                // Add the path to the database:
-               ret = rdb_add_path(pkg_id, label, path, "rwxatl", "PUBLIC_PATH");
+               ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "PUBLIC_PATH");
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("RDB rdb_add_path failed with: %d", ret);
                        return ret;
@@ -1221,14 +1063,13 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
                return PC_OPERATION_SUCCESS;
        }
 
-       case APP_PATH_SETTINGS: {
+       case APP_PATH_SETTINGS_RW: {
                C_LOGD("app_path_type is APP_PATH_SETTINGS.");
-               char **app_ids AUTO_FREE;
                const char *label;
                int ret;
 
                // Generate label:
-               label = smack_label_for_path(pkg_id, path);
+               label = smack_label_for_path(app_label, path);
                if (label == NULL) {
                        C_LOGE("smack_label_for_path failed.");
                        return PC_ERR_INVALID_OPERATION;
@@ -1236,14 +1077,14 @@ static int perm_app_setup_path_internal(const char* pkg_id, const char* path, ap
                C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
 
                /*set id for path and all subfolders*/
-               ret = app_label_shared_dir(pkg_id, label, path);
+               ret = app_label_shared_dir(app_label, label, path);
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
                        return ret;
                }
 
                // Add the path to the database:
-               ret = rdb_add_path(pkg_id, label, path, "rwxatl", "SETTINGS_PATH");
+               ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "SETTINGS_PATH");
                if (ret != PC_OPERATION_SUCCESS) {
                        C_LOGE("RDB rdb_add_path failed with: %d", ret);
                        return ret;
@@ -1282,7 +1123,6 @@ API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app
        return ret;
 }
 
-
 API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
@@ -1328,23 +1168,21 @@ API int perm_app_install(const char* pkg_id)
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
                                __func__, pkg_id);
        int ret;
-       int fd AUTO_CLOSE;
-       char* smack_path AUTO_FREE;
-       struct smack_accesses *smack AUTO_SMACK_FREE;
-
-       ret = perm_begin();
-       if(ret != PC_OPERATION_SUCCESS) {
-               C_LOGE("RDB perm_begin failed with: %d", ret);
-               return ret;
-       }
+       const char *app_label AUTO_FREE;
 
        if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param pkg_id.");
                return PC_ERR_INVALID_PARAM;
        }
 
+       app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
        // Add application to the database:
-       ret = rdb_add_application(pkg_id);
+       ret = rdb_add_application(app_label);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_add_application failed with: %d", ret);
                return ret;
@@ -1364,20 +1202,29 @@ API int app_uninstall(const char* pkg_id)//deprecated
 API int perm_app_uninstall(const char* pkg_id)
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
-       char* smack_path AUTO_FREE;
-       int ret;
+       /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+       /*int ret;
+       const char *app_label AUTO_FREE;*/
 
        if (!smack_label_is_valid(pkg_id)) {
                C_LOGE("Invalid param pkg_id.");
                return PC_ERR_INVALID_PARAM;
        }
 
+       SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
+       /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+       /*app_label = generate_app_label(pkg_id);
+       if (app_label == NULL) {
+               C_LOGE("generate_app_label returned NULL.");
+               return PC_ERR_MEM_OPERATION;
+       }
+
        // Remove application from the database
-       ret = rdb_remove_application(pkg_id);
+       ret = rdb_remove_application(app_label);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("RDB rdb_remove_application failed with: %d", ret);
                return ret;
-       }
+       }*/
 
        return PC_OPERATION_SUCCESS;
 }
@@ -1431,7 +1278,6 @@ API int perm_add_api_feature(app_type_t app_type,
                                __func__, app_type, api_feature_name);
 
        int ret = PC_OPERATION_SUCCESS;
-       char* smack_file AUTO_FREE;
        char* dac_file AUTO_FREE;
        char * base_api_feature_name AUTO_FREE;
        FILE* file = NULL;
@@ -1510,19 +1356,47 @@ API int app_register_av(const char* app_av_id UNUSED)//deprecated
        return PC_ERR_INVALID_OPERATION;
 }
 
-API int perm_add_additional_rules(const char** smack_rules){
-       SECURE_C_LOGD("Entering function: %s.", __func__);
-       int ret;
-       if (!smack_rules){
-               C_LOGE("smack_rules is NULL");
-               return PC_ERR_INVALID_PARAM;
+API const char* perm_strerror(int errnum)
+{
+       switch (errnum) {
+       case PC_OPERATION_SUCCESS:
+               return "Success";
+       case PC_ERR_FILE_OPERATION:
+               return "File operation error";
+       case PC_ERR_MEM_OPERATION:
+               return "Memory operation error";
+       case PC_ERR_NOT_PERMITTED:
+               return "Operation not permitted";
+       case PC_ERR_INVALID_PARAM:
+               return "Invalid parameter";
+       case PC_ERR_INVALID_OPERATION:
+               return "Invalid operation";
+       case PC_ERR_DB_OPERATION:
+               return "Database operation error";
+       case PC_ERR_DB_LABEL_TAKEN:
+               return "Label taken by another application";
+       case PC_ERR_DB_QUERY_PREP:
+               return "Query failure during preparation";
+       case PC_ERR_DB_QUERY_BIND:
+               return "Query failure during binding";
+       case PC_ERR_DB_QUERY_STEP:
+               return "Query failure during stepping";
+       case PC_ERR_DB_CONNECTION:
+               return "Cannot establish a connection";
+       case PC_ERR_DB_NO_SUCH_APP:
+               return "No such application";
+       case PC_ERR_DB_PERM_FORBIDDEN:
+               return "Duplicate permission";
+       default:
+               return "Unknown error";
        }
+}
 
-       ret = rdb_add_additional_rules(smack_rules);
-       if (ret != PC_OPERATION_SUCCESS) {
-               C_LOGE("RDB rdb_add_additional_rules failed with: %d", ret);
-               return ret;
-       }
+int app_give_access(const char* subject UNUSED, const char* object UNUSED, const char* permission UNUSED) {
 
-       return PC_OPERATION_SUCCESS;
+    return PC_ERR_INVALID_OPERATION;
+}
+
+int app_revoke_access(const char* subject UNUSED, const char* object UNUSED) {
+    return PC_ERR_INVALID_OPERATION;
 }