Implement perm_app_get_paths() API in libprivilege-control.
authorDamian Chromejko <d.chromejko@samsung.com>
Tue, 26 Nov 2013 15:47:23 +0000 (16:47 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 30 Jan 2014 11:47:56 +0000 (12:47 +0100)
[Issue#]       SSDWSSP-670
[Bug/Feature]  Add a function that retrieves a list of paths of a specified
               type for a given application.
[Cause]        Extending libprivilege-control API
[Solution]     Added a chain of functions extending existing API.
[Verification] Build, install, run tests.

Change-Id: I225668e57030d1bc32cee8e2169fc5070138eec0

include/common.h
include/privilege-control.h
include/rules-db-internals.h
include/rules-db.h
src/common.c
src/privilege-control.c
src/rules-db-internals.c
src/rules-db.c

index 2ffc389..54719ec 100644 (file)
@@ -147,6 +147,19 @@ const char* app_type_name(app_type_t app_type);
 const char* app_type_group_name(app_type_t app_type);
 
 /**
+ * Get the app path type name as stored in the database.
+ *
+ * This returns valid names only if paths of the given type are stored in the database.
+ * Otherwise NULL is returned.
+ *
+ * @ingroupd RDB itnernal functions
+ *
+ * @param  app_path_type type of the application's path
+ * @return name of the application's path or NULL if no matching type was found
+ */
+const char* app_path_type_name(app_path_type_t app_path_type);
+
+/**
  * Divide a Smack rule into subject, object and access
  *
  * @ingroup RDB internal functions
index 76eaa2f..20e2d90 100644 (file)
@@ -412,6 +412,25 @@ int add_shared_dir_readers(const char* shared_label, const char** app_list) DEPR
 int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...);
 int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...) DEPRECATED;
 
+/**
+ * Get paths of the specified type for the given application.
+ *
+ * Provided type must be one of PERM_APP_PATH_GROUP, PERM_APP_PATH_PUBLIC, PERM_APP_PATH_SETTINGS,
+ * PERM_APP_PATH_NPRUNTIME, as other types are not stored in the database.
+ *
+ * In case of success caller is responsible for freeing memory allocated by it.
+ * Each cell in *ppp_paths except for the last (NULL) should be freed, followed by freeing
+ * *ppp_paths itself.
+ *
+ * In case of error an error code is returned and, provided that ppp_paths is not NULL,
+ * *ppp_paths is set to NULL.
+ *
+ * @param  pkg_id        application identifier
+ * @param  app_path_type type of path
+ * @param  ppp_paths     buffer for return value
+ * @return               PC_OPERATION_SUCCESS on success, PC_ERR_* on error
+ */
+int perm_app_get_paths(const char* pkg_id, app_path_type_t app_path_type, char*** ppp_paths);
 
 /**
  * Make two applications "friends", by giving them both full permissions on
index 145e38b..0071961 100644 (file)
@@ -207,6 +207,40 @@ int add_path_internal(sqlite3 *p_db,
 
 
 /**
+ * Get number of paths of the specified type for the given application.
+ *
+ * @param  p_db                 pointer to a SQLite3 database object
+ * @param  s_app_label_name     application's label name
+ * @param  s_app_path_type_name name of the path type to get
+ * @param  p_num_paths          buffer for the return value
+ * @return                      PC_OPERATION_SUCCESS on success, PC_ERR_* on error
+ */
+int get_app_paths_count_internal(sqlite3 *p_db,
+                                const char *const s_app_label_name,
+                                const char *const s_app_path_type_name,
+                                int *const p_num_paths);
+
+
+/**
+ * Get paths of the specified type for the given application.
+ *
+ * @ingroup RDB API functions
+ *
+ * @param  p_db                 pointer to a SQLite3 database object
+ * @param  s_app_label_name     application's label name
+ * @param  s_app_path_type_name name of the path type to get
+ * @param  i_num_paths          number of paths
+ * @param  ppp_paths            buffer for return value
+ * @return                      PC_OPERATION_SUCCESS on success, PC_ERR_* on error
+ */
+int get_app_paths_internal(sqlite3 *p_db,
+                          const char *const s_app_label_name,
+                          const char *const s_app_path_type_name,
+                          const int i_num_paths,
+                          char ***ppp_paths);
+
+
+/**
  * Add a permission with a given name and of a give type
  * and return its internal permission id.
  *
index 38fafc6..6b0102a 100644 (file)
@@ -110,6 +110,20 @@ int rdb_add_path(const char *const s_owner_label_name,
 
 
 /**
+ * Get paths of the specified type for the given application.
+ *
+ * @ingroup RDB API functions
+ *
+ * @param s_app_label_name     application's label name
+ * @param s_app_path_type_name name of the path type to get
+ * @param ppp_paths            buffer for return value
+ * @return                     PC_OPERATION_SUCCESS on success, PC_ERR_* on error
+ */
+int rdb_get_app_paths(const char *const s_app_label_name,
+                     const char *const s_app_path_type_name,
+                     char ***ppp_paths);
+
+/**
  * Add permission with the given name and type and add smack rules.
  *
  * @ingroup RDB API functions
index 1a9d270..6ea9705 100644 (file)
@@ -436,6 +436,26 @@ inline const char* app_type_group_name(app_type_t app_type)
        }
 }
 
+const char* app_path_type_name(app_path_type_t app_path_type)
+{
+       SECURE_C_LOGD("Entering function %s. Params: app_path_type=%d", __func__, app_path_type);
+
+       switch(app_path_type) {
+       case PERM_APP_PATH_GROUP:
+               return "GROUP_PATH";
+       case PERM_APP_PATH_PUBLIC:
+               return "PUBLIC_PATH";
+       case PERM_APP_PATH_SETTINGS:
+               return "SETTINGS_PATH";
+       case PERM_APP_PATH_NPRUNTIME:
+               return "NPRUNTIME_PATH";
+       case PERM_APP_PATH_PRIVATE:
+       case PERM_APP_PATH_ANY_LABEL:
+       default:
+               // App path type not stored in the database, return NULL;
+               return NULL;
+       }
+}
 
 /**
  * This function changes permission URI to basename for file name.
index d626c35..42625ce 100644 (file)
@@ -1348,6 +1348,40 @@ API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_
        return ret;
 }
 
+API int perm_app_get_paths(const char* pkg_id, app_path_type_t app_path_type, char*** ppp_paths)
+{
+       SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_path_type=%d", __func__,
+                     pkg_id, app_path_type);
+
+       const char *path_type_name = app_path_type_name(app_path_type);
+       int ret;
+
+       if (ppp_paths == NULL) {
+               C_LOGE("Invalid param ppp_paths (NULL).");
+               return PC_ERR_INVALID_PARAM;
+       }
+       // Set the given pointer to NULL in case of future failure.
+       *ppp_paths = NULL;
+
+       if (path_type_name == NULL) {
+               C_LOGE("Unknown or invalid param app_path_type.");
+               return PC_ERR_INVALID_PARAM;
+       }
+
+       if (!smack_label_is_valid(pkg_id)) {
+               C_LOGE("Invalid param app_id.");
+               return PC_ERR_INVALID_PARAM;
+       }
+
+       ret = rdb_get_app_paths(pkg_id, path_type_name, ppp_paths);
+       if (ret != PC_OPERATION_SUCCESS) {
+               C_LOGE("RDB rdb_app_get_paths failed with: %d", ret);
+               return ret;
+       }
+
+       return PC_OPERATION_SUCCESS;
+}
+
 API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
 {
        SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
index 47778bf..dbc3de9 100644 (file)
@@ -447,6 +447,119 @@ finish:
        return ret;
 }
 
+int get_app_paths_count_internal(sqlite3 *p_db,
+                                const char *const s_app_label_name,
+                                const char *const s_app_path_type_name,
+                                int *const p_num_paths)
+{
+       RDB_LOG_ENTRY_PARAM("%s %s", s_app_label_name, s_app_path_type_name);
+
+       int ret;
+       int sql_ret;
+       sqlite3_stmt *p_stmt = NULL;
+
+       ret = prepare_stmt(p_db, &p_stmt,
+                          "SELECT COUNT(path)                   \
+                           FROM   path_view                     \
+                           WHERE  owner_app_label_name = %Q AND \
+                                  path_type_name = %Q",
+                          s_app_label_name, s_app_path_type_name);
+       if (ret != PC_OPERATION_SUCCESS) goto finish;
+
+       sql_ret = sqlite3_step(p_stmt);
+       if (sql_ret == SQLITE_ROW) {
+               ret = PC_OPERATION_SUCCESS;
+               *p_num_paths = sqlite3_column_int(p_stmt, RDB_FIRST_COLUMN);
+       } else if(sql_ret == SQLITE_BUSY) {
+               //base locked in exclusive mode for too long
+               C_LOGE("RDB: Database is busy. RDB Connection Error returned.");
+               ret = PC_ERR_DB_CONNECTION;
+       } else {
+               C_LOGE("RDB: Error during stepping: %s", sqlite3_errmsg(p_db));
+               ret = PC_ERR_DB_QUERY_STEP;
+       }
+
+finish:
+       if (sqlite3_finalize(p_stmt) < 0) {
+               C_LOGE("RDB: Error during finalizing statement: %s", sqlite3_errmsg(p_db));
+       }
+
+       return ret;
+}
+
+int get_app_paths_internal(sqlite3 *p_db,
+                          const char *const s_app_label_name,
+                          const char *const s_app_path_type_name,
+                          const int i_num_paths,
+                          char ***ppp_paths)
+{
+       RDB_LOG_ENTRY_PARAM("%s %s %d", s_app_label_name, s_app_path_type_name, i_num_paths);
+
+       int ret;
+       int sql_ret = SQLITE_DONE;
+       int allocated_paths = 0;
+       int i;
+       sqlite3_stmt *p_stmt = NULL;
+
+       // Allocate an array for paths (+1 for NULL pointer terminating *ppp_paths).
+       *ppp_paths = (char **) malloc(sizeof **ppp_paths * (i_num_paths + 1));
+
+       if (*ppp_paths == NULL) {
+               C_LOGE("Cannot allocate memory");
+               return PC_ERR_MEM_OPERATION;
+       }
+
+       ret = prepare_stmt(p_db, &p_stmt,
+                          "SELECT path                          \
+                           FROM   path_view                     \
+                           WHERE  owner_app_label_name = %Q AND \
+                                  path_type_name = %Q",
+                                  s_app_label_name, s_app_path_type_name);
+       if (ret != PC_OPERATION_SUCCESS) goto finish;
+
+       for (i = 0; i < i_num_paths; ++i) {
+               if ((sql_ret = sqlite3_step(p_stmt)) != SQLITE_ROW) break;
+
+               (*ppp_paths)[i] = strdup((const char *) sqlite3_column_text(p_stmt,
+                                       RDB_FIRST_COLUMN));
+
+               if ((*ppp_paths)[i] == NULL) {
+                       ret = PC_ERR_MEM_OPERATION;
+                       goto finish;
+               }
+
+               ++allocated_paths;
+       }
+       (*ppp_paths)[allocated_paths] = NULL;
+
+       if (allocated_paths == i_num_paths) {
+               ret = PC_OPERATION_SUCCESS;
+       } else if (sql_ret == SQLITE_BUSY) {
+               //base locked in exclusive mode for too long
+               C_LOGE("RDB: Database is busy. RDB Connection Error returned.");
+               ret = PC_ERR_DB_CONNECTION;
+       } else {
+               C_LOGE("RDB: Error during stepping: %s", sqlite3_errmsg(p_db));
+               ret = PC_ERR_DB_QUERY_STEP;
+       }
+
+finish:
+       if (ret != PC_OPERATION_SUCCESS) {
+               for(i = 0; i < allocated_paths; ++i) {
+                       free((*ppp_paths)[i]);
+               }
+
+               free(*ppp_paths);
+               *ppp_paths = NULL;
+       }
+
+       if (sqlite3_finalize(p_stmt) < 0) {
+               C_LOGE("RDB: Error during finalizing statement: %s", sqlite3_errmsg(p_db));
+       }
+
+       return ret;
+}
+
 
 int add_permission_internal(sqlite3 *p_db,
                            const char *const s_permission_name,
index 1ab78cf..6bf9b1a 100644 (file)
@@ -290,6 +290,35 @@ finish:
 }
 
 
+int rdb_get_app_paths(const char *const s_app_label_name,
+                     const char *const s_app_path_type_name,
+                     char ***ppp_paths)
+{
+       RDB_LOG_ENTRY_PARAM("%s %s", s_app_label_name, s_app_path_type_name);
+
+       int ret;
+       int i_num_paths;
+       sqlite3 *p_db = NULL;
+
+       ret = rdb_begin(&p_db, RDB_TRANSACTION_SHARED_READ);
+       if (ret != PC_OPERATION_SUCCESS) goto finish;
+
+       ret = get_app_paths_count_internal(p_db,
+                                          s_app_label_name,
+                                          s_app_path_type_name,
+                                          &i_num_paths);
+       if (ret != PC_OPERATION_SUCCESS) goto finish;
+
+       ret = get_app_paths_internal(p_db, s_app_label_name,
+                                    s_app_path_type_name,
+                                    i_num_paths,
+                                    ppp_paths);
+
+finish:
+       return rdb_finish(p_db, ret);
+}
+
+
 int rdb_add_permission_rules(const char *const s_permission_name,
                             const char *const s_permission_type_name,
                             const char *const *const pp_smack_rules)