From: Damian Chromejko Date: Fri, 22 Nov 2013 11:49:10 +0000 (+0100) Subject: Implement perm_app_get_permissions() API in libprivilege-control. X-Git-Tag: accepted/tizen/generic/20140307.163253~1^2~14 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fsecurity%2Flibprivilege-control.git;a=commitdiff_plain;h=c4cd0dfef511e4b07682fe9a6bbe1ceb5d3bfff2 Implement perm_app_get_permissions() API in libprivilege-control. [Issue#] SSDWSSP-669 [Bug/Feature] Add function to get a list of all permissions of a given type for the specified application. [Cause] Extending provided API. [Solution] Added a chain of functions extending existing API with necessary features. [Verification] Build, install, run tests. Change-Id: I0b3335191e50e954f95804463a2e073f1715e9db --- diff --git a/include/privilege-control.h b/include/privilege-control.h index 20e2d90..d3dbce6 100644 --- a/include/privilege-control.h +++ b/include/privilege-control.h @@ -329,6 +329,23 @@ int perm_app_has_permission(const char *pkg_id, bool *is_enabled); /** + * Get permissions for the specified app. + * + * In case of success caller is responsible for freeing memory allocated by it. + * Each cell in *ppp_perm_list except for the last (NULL) should be freed, followed by freeing + * *ppp_perm_list itself. + * + * In case of error an error code is returned and, provided that ppp_perm_list is not NULL, + * *ppp_perm_list is set to NULL. + * + * @param pkg_id application identifier + * @param app_type application type + * @param ppp_perm_list buffer for return value + * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error + */ +int perm_app_get_permissions(const char *pkg_id, app_type_t app_type, char ***ppp_perm_list); + +/** * Recursively set SMACK access labels for an application directory * and execute labels for executable files. * This function should be called once during app installation. diff --git a/include/rules-db-internals.h b/include/rules-db-internals.h index 0071961..7d619be 100644 --- a/include/rules-db-internals.h +++ b/include/rules-db-internals.h @@ -304,6 +304,37 @@ int check_app_has_permission_internal(sqlite3 *p_db, /** + * Get number of permission of a certain type for the specified app. + * + * @param p_db pointer to a SQLite3 database object + * @param s_app_label_name application label's name + * @param s_permission_type_name permission type's name + * @param p_num_permissions buffer for return value + * @return PC_OPERATION_SUCCESS on success, error code otherwise + */ +int get_app_permissions_number_internal(sqlite3 *p_db, + const char *const s_app_label_name, + const char *const s_permission_type_name, + int *const p_num_permissions); + +/** + * Get permissions for the specified app. + * + * @param p_db pointer to a SQLite3 database object + * @param s_app_label_name application label's name + * @param s_permission_type_name permission type's name + * @param i_num_permissions number of permissions of the specified type + * @param ppp_perm_list buffer for return value + * @return PC_OPERATION_SUCCESS on success, error code otherwise + */ +int get_app_permissions_internal(sqlite3 *p_db, + const char *const s_app_label_name, + const char *const s_permission_type_name, + const int i_num_permissions, + char ***ppp_perm_list); + + +/** * Gets the internal app id of an application with a given name. * * @ingroup RDB internal functions diff --git a/include/rules-db.h b/include/rules-db.h index 6b0102a..11570e5 100644 --- a/include/rules-db.h +++ b/include/rules-db.h @@ -231,4 +231,20 @@ int rdb_app_has_permission(const char *const s_app_label_name, const char *const s_permission_name, bool *const p_is_enabled); + +/** + * Get permissions for the specified app. + * + * @ingroup RDB API functions + * + * @param s_app_label_name application label's name + * @param s_permission_type_name permission type's name + * @param ppp_perm_list buffer for return value + * @return PC_OPERATION_SUCCESS on success, + * error code otherwise + */ +int rdb_app_get_permissions(const char *const s_app_label_name, + const char *const s_permission_type_name, + char ***ppp_perm_list); + #endif /*_RULES_DB_H_*/ diff --git a/src/privilege-control.c b/src/privilege-control.c index 42625ce..cb373b8 100644 --- a/src/privilege-control.c +++ b/src/privilege-control.c @@ -1027,6 +1027,40 @@ API int perm_app_has_permission(const char *pkg_id, return rdb_app_has_permission(pkg_id, app_group, permission_name, is_enabled); } +API int perm_app_get_permissions(const char *pkg_id, app_type_t app_type, char ***ppp_perm_list) +{ + SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d", __func__, pkg_id, + app_type); + + const char *app_group = app_type_group_name(app_type); + int ret; + + if (ppp_perm_list == NULL) { + C_LOGE("Invalid param ppp_perm_list (NULL)."); + return PC_ERR_INVALID_PARAM; + } + // Set the given pointer to NULL in case of future failure. + *ppp_perm_list = NULL; + + if (app_group == NULL) { + C_LOGE("Unknown param app 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_app_get_permissions(pkg_id, app_group, ppp_perm_list); + if (ret != PC_OPERATION_SUCCESS) { + C_LOGE("RDB rdb_app_get_permissions failed with: %d", ret); + return ret; + } + + return PC_OPERATION_SUCCESS; +} + API int app_label_dir(const char* label, const char* path)//deprecated { SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s", diff --git a/src/rules-db-internals.c b/src/rules-db-internals.c index dbc3de9..b4ed4ae 100644 --- a/src/rules-db-internals.c +++ b/src/rules-db-internals.c @@ -1024,6 +1024,121 @@ finish: return ret; } + +int get_app_permissions_number_internal(sqlite3 *p_db, const char *const s_app_label_name, + const char *const s_permission_type_name, + int *const p_num_permissions) +{ + RDB_LOG_ENTRY_PARAM("%s %s", s_app_label_name, s_permission_type_name); + + int ret; + int sql_ret; + sqlite3_stmt *p_stmt = NULL; + + ret = prepare_stmt(p_db, &p_stmt, + "SELECT COUNT(name) \ + FROM app_permission_view \ + WHERE app_name = %Q AND \ + is_enabled = 1 AND \ + type_name = %Q", + s_app_label_name, s_permission_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_permissions = 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_permissions_internal(sqlite3 *p_db, + const char *const s_app_label_name, + const char *const s_permission_type_name, + const int i_num_permissions, + char ***ppp_perm_list) +{ + RDB_LOG_ENTRY_PARAM("%s %s %d", s_app_label_name, s_permission_type_name, + i_num_permissions); + + int ret; + int sql_ret = SQLITE_DONE; + int allocated_permissions = 0; + int i; + sqlite3_stmt *p_stmt = NULL; + + // Allocate an array for permissions (+1 for NULL pointer terminating *ppp_perm_list). + *ppp_perm_list = (char **) malloc(sizeof **ppp_perm_list * (i_num_permissions + 1)); + if (*ppp_perm_list == NULL) { + C_LOGE("Cannot allocate memory"); + return PC_ERR_MEM_OPERATION; + } + + // Get the permissions themselves. + ret = prepare_stmt(p_db, &p_stmt, + "SELECT name \ + FROM app_permission_view \ + WHERE app_name = %Q AND \ + is_enabled = 1 AND \ + type_name = %Q", + s_app_label_name, s_permission_type_name); + if (ret != PC_OPERATION_SUCCESS) goto finish; + + for (i = 0; i < i_num_permissions; ++i) { + if ((sql_ret = sqlite3_step(p_stmt)) != SQLITE_ROW) break; + + (*ppp_perm_list)[i] = strdup((const char *) sqlite3_column_text(p_stmt, + RDB_FIRST_COLUMN)); + + if ((*ppp_perm_list)[i] == NULL) { + ret = PC_ERR_MEM_OPERATION; + goto finish; + } + + ++allocated_permissions; + } + (*ppp_perm_list)[allocated_permissions] = NULL; + + if (allocated_permissions == i_num_permissions) { + ret = PC_OPERATION_SUCCESS; + } else if (sql_ret == SQLITE_BUSY) { + 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_permissions; ++i) { + free((*ppp_perm_list)[i]); + } + free(*ppp_perm_list); + *ppp_perm_list = NULL; + } + + if (sqlite3_finalize(p_stmt) < 0) { + C_LOGE("RDB: Error during finalizing statement: %s", sqlite3_errmsg(p_db)); + } + + return ret; +} + + int get_app_id_internal(sqlite3 *p_db, int *pi_app_id, const char *const s_app_label_name) diff --git a/src/rules-db.c b/src/rules-db.c index 6bf9b1a..26e84e5 100644 --- a/src/rules-db.c +++ b/src/rules-db.c @@ -547,3 +547,32 @@ int rdb_app_has_permission(const char *const s_app_label_name, finish: return rdb_finish(p_db, ret); } + +int rdb_app_get_permissions(const char *const s_app_label_name, + const char *const s_permission_type_name, + char ***ppp_perm_list) +{ + RDB_LOG_ENTRY_PARAM("%s %s", s_app_label_name, s_permission_type_name); + + int ret = PC_ERR_DB_OPERATION; + int i_num_permissions; + sqlite3 *p_db = NULL; + + ret = rdb_begin(&p_db, RDB_TRANSACTION_SHARED_READ); + if(ret != PC_OPERATION_SUCCESS) goto finish; + + ret = get_app_permissions_number_internal(p_db, + s_app_label_name, + s_permission_type_name, + &i_num_permissions); + if (ret != PC_OPERATION_SUCCESS) goto finish; + + ret = get_app_permissions_internal(p_db, + s_app_label_name, + s_permission_type_name, + i_num_permissions, + ppp_perm_list); + +finish: + return rdb_finish(p_db, ret); +}