Add implementation for appsetting privilege
authorJan Cybulski <j.cybulski@samsung.com>
Thu, 23 May 2013 10:12:28 +0000 (12:12 +0200)
committerGerrit Code Review <gerrit2@kim11>
Mon, 3 Jun 2013 14:46:21 +0000 (23:46 +0900)
    [Issue#]        SSDWSSP-241
    [Bug/Feature]   Implement an unique feature for an appsetting privilege.
                    The privilege should give RWX access to all registered
                    setting folders and RX access to all applications.
    [Cause]         N/A
    [Solution]      Change in app_add_permissions_internal.
    [Verification]  Run libprivilege tests.
                    Test privilege_control16_appsettings_privilege should pass

Change-Id: Icdb2b6dc44395ec7a723064bc2db56ef634e609d

.privilege_control_app_setting.db [new file with mode: 0644]
.privilege_control_setting_dir.db [new file with mode: 0644]
CMakeLists.txt
include/access-db.h
packaging/libprivilege-control-conf.manifest
src/access-db.c
src/privilege-control.c

diff --git a/.privilege_control_app_setting.db b/.privilege_control_app_setting.db
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.privilege_control_setting_dir.db b/.privilege_control_setting_dir.db
new file mode 100644 (file)
index 0000000..e69de29
index 12259e1..26a1d68 100644 (file)
@@ -84,5 +84,7 @@ INSTALL(FILES .privilege_control_all_apps_id.db DESTINATION /opt/dbspace)
 INSTALL(FILES .privilege_control_all_avs_id.db DESTINATION /opt/dbspace)
 INSTALL(FILES .privilege_control_app_gids.db DESTINATION /opt/dbspace)
 INSTALL(FILES .privilege_control_public_dirs.db DESTINATION /opt/dbspace)
+INSTALL(FILES .privilege_control_app_setting.db DESTINATION /opt/dbspace)
+INSTALL(FILES .privilege_control_setting_dir.db DESTINATION /opt/dbspace)
 #INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/udev/ DESTINATION lib/udev)
 INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/slp-su DESTINATION bin)
index c0e688c..3e865e1 100644 (file)
@@ -35,11 +35,41 @@ int add_app_id_to_databse(const char * app_id);
 int add_av_id_to_databse(const char * av_id);
 
 /**
+ * This function add appsetting_id to database.
+ * Needs to be call by privileged user.
+ */
+int add_appsetting_id_to_databse(const char *appsetting_id);
+
+/**
+ * This function add setting_dir_id to database.
+ * Needs to be call by privileged user.
+ */
+int add_setting_dir_id_to_databse(const char *setting_dir_id);
+
+
+/**
  * This function returns (in params) labels of all installed applications.
  * apps_ids should be freed by caller.
  */
 int get_all_apps_ids(char *** apps_ids, int * len);
 
+
+/**
+ * This function returns (in params) labels of all registered settings dirs of
+ * all installed applications.
+ * apps_ids should be freed by caller.
+ */
+int get_all_settings_dir_ids(char ***apps_ids, int *len);
+
+
+/**
+ * This function returns (in params) labels of all registered apps with
+ * appsettings privilege
+ *
+ * apps_ids should be freed by caller.
+ */
+int get_all_appsetting_ids(char ***apps_ids, int *len);
+
 /**
  * This function returns (in params) labels of all installed anti viruses.
  * avs_ids should be freed by caller.
index fd401ab..e178289 100644 (file)
@@ -39,5 +39,7 @@
                <filesystem path="/opt/dbspace/.privilege_control_all_avs_id.db" label="system::privilege_control::db"/>
                <filesystem path="/opt/dbspace/.privilege_control_app_gids.db" label="system::privilege_control::db"/>
                <filesystem path="/opt/dbspace/.privilege_control_public_dirs.db" label="system::privilege_control::db"/>
+               <filesystem path="/opt/dbspace/.privilege_control_setting_dir.db" label="system::privilege_control::db"/>
+               <filesystem path="/opt/dbspace/.privilege_control_app_setting.db" label="system::privilege_control::db"/>
        </assign>
 </manifest>
index 05d0bd4..b138271 100644 (file)
@@ -37,6 +37,8 @@ typedef enum {
        DB_APP_TYPE_ANTIVIRUS,
        DB_APP_TYPE_GROUPS,
        DB_APP_TYPE_PUBLIC_DIRS,
+       DB_APP_TYPE_APPSETTING,
+       DB_APP_TYPE_SETTING_DIR,
        DB_APP_TYPE_COUNT /* Dummy enum element to get number of elements */
 } db_app_type_t;
 
@@ -45,6 +47,8 @@ const char* db_file_names[DB_APP_TYPE_COUNT] = {
                "/opt/dbspace/.privilege_control_all_avs_id.db",
                "/opt/dbspace/.privilege_control_app_gids.db",
                "/opt/dbspace/.privilege_control_public_dirs.db",
+               "/opt/dbspace/.privilege_control_app_setting.db",
+               "/opt/dbspace/.privilege_control_setting_dir.db",
 };
 
 typedef struct element_s {
@@ -208,6 +212,22 @@ int get_all_apps_ids (char *** apps_ids, int * len)
        return PC_OPERATION_SUCCESS;
 }
 
+int get_all_settings_dir_ids(char ***apps_ids, int *len)
+{
+       if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_SETTING_DIR))
+               return PC_ERR_DB_OPERATION;
+
+       return PC_OPERATION_SUCCESS;
+}
+
+int get_all_appsetting_ids(char ***apps_ids, int *len)
+{
+       if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_APPSETTING))
+               return PC_ERR_DB_OPERATION;
+
+       return PC_OPERATION_SUCCESS;
+}
+
 int get_all_avs_ids (char *** av_ids, int * len)
 {
        if (get_all_ids_internal(av_ids, len, DB_APP_TYPE_ANTIVIRUS))
@@ -236,6 +256,27 @@ int add_av_id_to_databse (const char * av_id)
        return PC_OPERATION_SUCCESS;
 }
 
+int add_appsetting_id_to_databse(const char *appsetting_id)
+{
+       C_LOGD("Enter function: %s", __func__);
+
+       if (add_id_to_database_internal(appsetting_id, DB_APP_TYPE_APPSETTING))
+               return PC_ERR_DB_OPERATION;
+
+       return PC_OPERATION_SUCCESS;
+}
+
+int add_setting_dir_id_to_databse(const char *setting_dir_id)
+{
+       C_LOGD("Enter function: %s", __func__);
+
+       if (add_id_to_database_internal(
+                       setting_dir_id, DB_APP_TYPE_SETTING_DIR))
+               return PC_ERR_DB_OPERATION;
+
+       return PC_OPERATION_SUCCESS;
+}
+
 int add_app_gid(const char *app_id, unsigned gid)
 {
        C_LOGD("Enter function: %s", __func__);
index f33599f..fd7484b 100644 (file)
@@ -70,6 +70,9 @@
 #define WRT_CLIENT_PATH         "/usr/bin/wrt-client"
 #define ACC_LEN                 5
 #define TIZEN_PRIVILEGE_ANTIVIRUS "http://tizen.org/privilege/antivirus"
+#define TIZEN_PRIVILEGE_APPSETTING "http://tizen.org/privilege/appsetting"
+
+
 
 typedef struct {
        char user_name[10];
@@ -1052,6 +1055,78 @@ static int app_add_rule(const char *app_id, const char *object, const char *perm
        return PC_OPERATION_SUCCESS;
 }
 
+
+static int
+app_register_appsetting(const char *app_id, struct smack_accesses *smack)
+{
+       C_LOGD("Enter function: %s", __func__);
+       int ret;
+       int i;
+
+       char **label_app_list AUTO_FREE;
+       char **label_dir_list AUTO_FREE;
+       int app_list_len = 0;
+       int dir_list_len = 0;
+
+       if (!smack_label_is_valid(app_id))
+               return PC_ERR_INVALID_PARAM;
+
+
+       /* writing appsetting_id (app_id) to "database"*/
+       ret = add_appsetting_id_to_databse(app_id);
+       if (ret != PC_OPERATION_SUCCESS)
+               goto out;
+
+
+       /* Reading labels of all installed apps from "database"*/
+       ret = get_all_apps_ids(&label_app_list, &app_list_len);
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("Error while geting data from database");
+               goto out;
+       }
+
+       /*Add smack rules to rx access each app*/
+       for (i = 0; i < app_list_len; ++i) {
+               C_LOGD("Appsetting: applying rx rule for %s", label_app_list[i]);
+               if (smack_accesses_add(smack, app_id,
+                               label_app_list[i], "rx") == -1) {
+                       C_LOGE("smack_accesses_add failed");
+                       ret = PC_ERR_INVALID_OPERATION;
+                       goto out;
+               }
+       }
+
+       /* Reading labels of all registered settings dirs from "database"*/
+       ret = get_all_settings_dir_ids(
+                       &label_dir_list, &dir_list_len);
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("Error while geting data from database");
+               goto out;
+       }
+       /*Add smack rules to rwx access each app*/
+       for (i = 0; i < dir_list_len; ++i) {
+               C_LOGD("Appsetting: applying rwx rule for %s", label_dir_list[i]);
+               if (smack_accesses_add(smack, app_id,
+                               label_dir_list[i], "rwx") == -1) {
+                       C_LOGE("smack_accesses_add failed");
+                       ret = PC_ERR_INVALID_OPERATION;
+                       goto out;
+                       /* Should we abort adding rules if once
+                        * smack_accesses_add will fail?*/
+               }
+       }
+
+       out:
+       for (i = 0; i < app_list_len; ++i) {
+               free(label_app_list[i]);
+       }
+       for (i = 0; i < dir_list_len; ++i) {
+               free(label_dir_list[i]);
+       }
+
+       return ret;
+}
+
 static int app_register_av_internal(const char *app_av_id, struct smack_accesses* smack)
 {
        C_LOGD("Enter function: %s", __func__);
@@ -1135,6 +1210,50 @@ out:
 }
 
 /**
+ *  This function will check in database labels of all setting applications
+ *  and for all of them will add a rule "appsetting_id app_id rwx".
+ *  This should be call in app_install function.
+ */
+static int register_app_for_appsetting(const char *app_id)
+{
+       C_LOGD("Enter function: %s",__func__);
+       int ret, i;
+       char **smack_label_list AUTO_FREE;
+       int smack_label_list_len = 0;
+
+       /* Reading labels of all installed setting managers from "database"*/
+       ret = get_all_appsetting_ids(&smack_label_list, &smack_label_list_len);
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("Error while geting data from database");
+               return ret;
+       }
+
+       /* for each appsetting put rule: "appsetting_id app_id rx"*/
+       for (i = 0; i < smack_label_list_len; ++i) {
+               C_LOGD("Appsetting: app_add_rule (%s, %s rx)", smack_label_list[i], app_id);
+               ret = app_add_rule(smack_label_list[i], app_id, "rx");
+               if (ret != PC_OPERATION_SUCCESS) {
+                       C_LOGE("app_add_rule failed");
+                       goto out;
+               }
+
+               free(smack_label_list[i]);
+       }
+
+       ret = PC_OPERATION_SUCCESS;
+
+out:
+       /* If something failed, then no all char* smack_label_list[i]
+        are deallocated. They must be freed*/
+       for (; i < smack_label_list_len; ++i) {
+               free(smack_label_list[i]);
+       }
+
+       return ret;
+}
+
+
+/**
  *  This function will grant app_id RX access to all public directories and
  *  files, previously designated by app_setup_path(APP_PATH_PUBLIC_RO)
  *  This should be call in app_install function.
@@ -1203,6 +1322,14 @@ static int app_add_permissions_internal(const char* app_id, app_type_t app_type,
                                return ret;
                        }
                }
+               if (strcmp(perm_list[i], TIZEN_PRIVILEGE_APPSETTING) == 0) {
+                       ret = app_register_appsetting(app_id, smack);
+                       if (ret != PC_OPERATION_SUCCESS) {
+                               C_LOGE("app_register_appsetting failed");
+                               return ret;
+                       }
+               }
+
                ret = perm_to_smack(smack, app_id, app_type, perm_list[i]);
                if (ret != PC_OPERATION_SUCCESS){
                        C_LOGE("perm_to_smack failed");
@@ -1528,7 +1655,6 @@ static char* smack_label_for_path(const char *app_id, const char *path)
 
        return label;
 }
-
 /* FIXME: remove this pragma once deprecated API is deleted */
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 API int app_setup_path(const char* app_id, const char* path, app_path_type_t app_path_type, ...)
@@ -1611,11 +1737,62 @@ API int app_setup_path(const char* app_id, const char* path, app_path_type_t app
        }
 
        case APP_PATH_SETTINGS_RW:
+       {
+               char **app_ids AUTO_FREE;
+               int app_ids_cnt = 0;
+               const char *label;
+               int i;
+               int ret;
+
                va_start(ap, app_path_type);
                va_end(ap);
-               /* TODO */
-               break;
 
+               /*get path id*/
+               label = smack_label_for_path(app_id, path);
+               if (label == NULL)
+                       return PC_ERR_INVALID_OPERATION;
+
+               /*set id for path and all subfolders*/
+               C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
+               ret = app_label_shared_dir(app_id, label, path);
+               if (ret != PC_OPERATION_SUCCESS) {
+                       C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
+                       return ret;
+               }
+
+               /*add path to database*/
+               /* FIXME: This should be in some kind of transaction/lock */
+               ret = add_setting_dir_id_to_databse(label);
+               if (ret != PC_OPERATION_SUCCESS) {
+                       C_LOGE("Appsetting: add_setting_dir_id_to_databse failed");
+                       return ret;
+               }
+
+               /*read all apps with appsetting privilege*/
+               ret = get_all_appsetting_ids(&app_ids, &app_ids_cnt);
+               if (ret != PC_OPERATION_SUCCESS) {
+                       C_LOGE("Appsetting: get_all_appsetting_ids failed");
+                       return ret;
+               }
+               C_LOGD("Appsetting: %d appsetting privileged apps registeres",
+                               app_ids_cnt);
+
+               /*give RWX rights to all apps that have appsetting privilege*/
+               for (i = 0; i < app_ids_cnt; ++i) {
+                       C_LOGD("Appsetting: allowing app %s to access setting path %s",
+                                       app_ids[i], label);
+                       ret = app_add_rule(app_ids[i], label, "rwx");
+                       if (ret != PC_OPERATION_SUCCESS) {
+                               C_LOGE("app_add_rule failed");
+                               while (i < app_ids_cnt)
+                                       free(app_ids[i++]);
+                               return ret;
+                       }
+                       free(app_ids[i]);
+               }
+
+               return PC_OPERATION_SUCCESS;
+       }
        default:
                va_start(ap, app_path_type);
                va_end(ap);
@@ -1688,6 +1865,12 @@ API int app_install(const char* app_id)
                return ret;
        }
 
+       ret = register_app_for_appsetting(app_id);
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("Error while adding rules for setting managers to app %s: %s ", app_id, strerror(errno));
+               return ret;
+       }
+
        ret = register_app_for_public_dirs(app_id, smack);
        if (ret != PC_OPERATION_SUCCESS) {
                C_LOGE("Error while adding rules for access to public dirs for app %s: %s ", app_id, strerror(errno));