#include <string.h>
#include <sys/smack.h>
#include <dlog.h>
+#include <ctype.h>
#include "privilege-control.h"
-#define SMACK_APPS_LABELS_DATABASE "/opt/dbspace/.privilege_control_all_apps_id.db"
-#define SMACK_AVS_LABELS_DATABASE "/opt/dbspace/.privilege_control_all_avs_id.db"
-
#ifdef LOG_TAG
#undef LOG_TAG
#endif // LOG_TAG
typedef enum {
DB_APP_TYPE_APPLICATION,
DB_APP_TYPE_ANTIVIRUS,
+ DB_APP_TYPE_GROUPS,
+ DB_APP_TYPE_COUNT /* Dummy enum element to get number of elements */
} db_app_type_t;
+const char* db_file_names[DB_APP_TYPE_COUNT] = {
+ "/opt/dbspace/.privilege_control_all_apps_id.db",
+ "/opt/dbspace/.privilege_control_all_avs_id.db",
+ "/opt/dbspace/.privilege_control_app_gids.db",
+};
+
typedef struct element_s {
struct element_s* next;
char* value;
C_LOGD("Enter function: %s", __func__);
int ret;
FILE* file_db = NULL;
- char* db_type;
+ const char* db_file_name = db_file_names[app_type];
- if (DB_APP_TYPE_APPLICATION == app_type) {
- db_type = SMACK_APPS_LABELS_DATABASE;
- }
- else if (DB_APP_TYPE_ANTIVIRUS == app_type) {
- db_type = SMACK_AVS_LABELS_DATABASE;
- }
- else {
- return PC_ERR_INVALID_PARAM;
- }
-
- file_db = fopen(db_type, "a");
+ file_db = fopen(db_file_name, "a");
if (NULL == file_db) {
- C_LOGE("Error while opening database file: %s", db_type);
+ C_LOGE("Error while opening database file: %s", db_file_name);
ret = PC_ERR_FILE_OPERATION;
goto out;
}
int ret;
char* scanf_label_format = NULL;
FILE* file_db = NULL;
- char* db_type;
+ const char* db_file_name = db_file_names[app_type];
char smack_label[SMACK_LABEL_LEN + 1];
element_t* begin_of_list = NULL;
- if (DB_APP_TYPE_APPLICATION == app_type) {
- db_type = SMACK_APPS_LABELS_DATABASE;
- } else if (DB_APP_TYPE_ANTIVIRUS == app_type) {
- db_type = SMACK_AVS_LABELS_DATABASE;
- } else {
- return PC_ERR_INVALID_PARAM;
- }
-
if (asprintf(&scanf_label_format, "%%%ds\\n", SMACK_LABEL_LEN) < 0) {
C_LOGE("Error while creating scanf input label format");
ret = PC_ERR_MEM_OPERATION;
goto out;
}
- file_db = fopen(db_type, "r");
+ file_db = fopen(db_file_name, "r");
if (NULL == file_db) {
- C_LOGE("Error while opening antivirus_ids database file: %s", db_type);
+ C_LOGE("Error while opening antivirus_ids database file: %s", db_file_name);
ret = PC_ERR_FILE_OPERATION;
goto out;
}
return PC_OPERATION_SUCCESS;
}
+
+int add_app_gid(const char *app_id, unsigned gid)
+{
+ C_LOGD("Enter function: %s", __func__);
+ char *field = NULL;
+ int ret;
+
+ ret = asprintf(&field, "%u:%s", gid, app_id);
+ if (ret == -1)
+ return PC_ERR_MEM_OPERATION;
+
+ ret = add_id_to_database_internal(field, DB_APP_TYPE_GROUPS);
+ free(field);
+
+ return ret;
+}
+
+int get_app_gids(const char *app_id, unsigned **gids, int *len)
+{
+ char** fields;
+ int len_tmp, ret, i;
+
+ ret = get_all_ids_internal(&fields, &len_tmp, DB_APP_TYPE_GROUPS);
+ if (ret != PC_OPERATION_SUCCESS)
+ return ret;
+
+ *len = 0;
+ *gids = NULL;
+ for (i = 0; i < len_tmp; ++i) {
+ const char *field = fields[i];
+ const char *app_id_tmp = NULL;
+ unsigned gid = 0;
+
+ for (; *field; ++field) {
+ if (*field == ':') {
+ app_id_tmp = field + 1;
+ break;
+ }
+ if (isdigit(*field)) {
+ gid = gid * 10 + *field - '0';
+ } else {
+ C_LOGE("Invalid line read: %s", fields[i]);
+ ret = PC_ERR_FILE_OPERATION;
+ goto out;
+ }
+ }
+
+ if (!strcmp(app_id, app_id_tmp)) {
+ unsigned *gids_realloc = realloc(*gids, sizeof(unsigned) * (*len + 1));
+ if (gids_realloc == NULL) {
+ C_LOGE("Memory allocation failed");
+ ret = PC_ERR_MEM_OPERATION;
+ goto out;
+ }
+ *gids = gids_realloc;
+ (*gids)[(*len)++] = gid;
+ }
+ }
+
+ ret = PC_OPERATION_SUCCESS;
+out:
+ for (i = 0; i < len_tmp; ++i)
+ free(fields[i]);
+ free(fields);
+
+ if (ret != PC_OPERATION_SUCCESS) {
+ free(*gids);
+ *len = 0;
+ }
+
+ return ret;
+}
#define APP_GID 5000
#define APP_UID 5000
+#define ADMIN_GROUP 6504
#define DEVELOPER_GID 5100
#define DEVELOPER_UID 5100
int result;
int i;
new_user usr;
+ char *current_smack = NULL;
+ unsigned *additional_gids = NULL;
/*
* initialize user structure
fp_group = NULL;
/*
+ * in case of dialer, add admin to glist
+ */
+ if(!strncmp(pkg_name, "com.samsung.phone", 17) || !strncmp(pkg_name, "com.samsung.call", 16) ||
+ !strncmp(pkg_name, "phone-tabui-efl", 15))
+ {
+ gid_t *glist_new;
+ C_LOGD("Dialer app - add admin to glist");
+ glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + 1));
+ if (glist_new == NULL) {
+ result = PC_ERR_MEM_OPERATION; // return -2
+ C_LOGE("Cannot allocate memory");
+ goto error;
+ }
+ glist = glist_new;
+ glist[glist_cnt] = ADMIN_GROUP; // 6504
+ glist_cnt++;
+ }
+
+#ifdef SMACK_ENABLED
+ {
+ gid_t *glist_new;
+ int i, cnt;
+
+ if (smack_new_label_from_self(¤t_smack)) {
+ C_LOGE("smack_new_label_from_self failed");
+ result = PC_ERR_MEM_OPERATION;
+ goto error;
+ }
+ result = get_app_gids(current_smack, &additional_gids, &cnt);
+ if (result != PC_OPERATION_SUCCESS)
+ goto error;
+
+ if (cnt > 0) {
+ glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + cnt));
+ if (glist_new == NULL) {
+ result = PC_ERR_MEM_OPERATION; // return -2
+ C_LOGE("Cannot allocate memory");
+ goto error;
+ }
+ glist = glist_new;
+ for (i = 0; i < cnt; ++i) {
+ C_LOGD("Additional GID based on enabled permissions: %u", additional_gids[i]);
+ glist[glist_cnt++] = additional_gids[i];
+ }
+ }
+ }
+#endif
+
+ /*
* setgroups()
*/
C_LOGD("Adding process to the following groups:");
fclose(fp_group);
if(glist != NULL)
free(glist);
+ free(additional_gids);
+ free(current_smack);
return result;
}
return set_app_privilege(pkg_name, NULL, NULL);
}
-#ifdef SMACK_ENABLED
static inline const char* app_type_name(app_type_t app_type)
{
switch (app_type) {
}
}
-static int perm_file(app_type_t app_type, const char* devcap, char** path) {
+static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix)
+{
const char* app_type_prefix = NULL;
- const char* perm_suffix = NULL;
+ const char* perm_basename = NULL;
int ret = 0;
- if (devcap == NULL || strlen(devcap) == 0) {
- C_LOGE("empty devcap");
+ if (perm == NULL || strlen(perm) == 0) {
+ C_LOGE("empty permission name");
return PC_ERR_INVALID_PARAM;
}
app_type_prefix = app_type_name(app_type);
- perm_suffix = strrchr(devcap, '/');
- if (perm_suffix)
- ++perm_suffix;
+ perm_basename = strrchr(perm, '/');
+ if (perm_basename)
+ ++perm_basename;
else
- perm_suffix = devcap;
+ perm_basename = perm;
- ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s.smack",
+ ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
- perm_suffix);
+ perm_basename, suffix);
if (ret == -1) {
C_LOGE("asprintf failed");
return PC_ERR_MEM_OPERATION;
}
+
return PC_OPERATION_SUCCESS;
}
+#ifdef SMACK_ENABLED
static bool file_exists(const char* path) {
FILE* file = fopen(path, "r");
if (file) {
char smack_accesses[10];
// get file name for permission (devcap)
- ret = perm_file(app_type, perm, &path);
- if (ret != PC_OPERATION_SUCCESS)
- {
- free(path);
- return ret;
+ ret = perm_file_path(&path, app_type, perm, ".smack");
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGD("No smack config file for permission %s", perm);
+ goto out;
}
if (asprintf(&format_string,"%%%ds %%%ds %%%lus\n",
fclose(file);
return ret;
}
+#endif //SMACK_ENABLED
+
+static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
+{
+ C_LOGD("Enter function: %s", __func__);
+ int ret;
+ char* path = NULL;
+ FILE* file = NULL;
+ int gid;
+
+ ret = perm_file_path(&path, app_type, perm, ".dac");
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGD("No dac config file for permission %s", perm);
+ goto out;
+ }
+
+ file = fopen(path, "r");
+ C_LOGD("path = %s", path);
+ if (file == NULL) {
+ C_LOGE("fopen failed");
+ ret = PC_OPERATION_SUCCESS;
+ goto out;
+ }
+
+ while (fscanf(file, "%d\n", &gid) == 1) {
+ C_LOGD("Adding app_id %s to group %d", app_label, gid);
+ ret = add_app_gid(app_label, gid);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("sadd_app_gid failed");
+ goto out;
+ }
+ }
+
+ ret = PC_OPERATION_SUCCESS;
+
+out:
+ free(path);
+ if (file != NULL)
+ fclose(file);
+ return ret;
+}
+#ifdef SMACK_ENABLED
static int dir_set_smack_r(const char *path, const char* label,
enum smack_label_type type, mode_t type_mask)
{
static int app_add_permissions_internal(const char* app_id, app_type_t app_type, const char** perm_list, int permanent)
{
C_LOGD("Enter function: %s", __func__);
+ int i, ret = PC_OPERATION_SUCCESS;
#ifdef SMACK_ENABLED
- char* smack_path = NULL;
- int i, ret;
int fd = -1;
+ char* smack_path = NULL;
struct smack_accesses *smack = NULL;
const char* base_perm = NULL;
goto out;
}
}
-
+#endif // SMACK_ENABLED
for (i = 0; perm_list[i] != NULL; ++i) {
+#ifdef SMACK_ENABLED
C_LOGD("perm_to_smack params: app_id: %s, perm_list[%d]: %s", app_id, i, perm_list[i]);
ret = perm_to_smack(smack, app_id, app_type, perm_list[i]);
if (ret != PC_OPERATION_SUCCESS){
C_LOGE("perm_to_smack failed");
goto out;
}
+#endif //SMACK_ENABLED
+ ret = perm_to_dac(app_id, app_type, perm_list[i]);
+ if (ret != PC_OPERATION_SUCCESS){
+ C_LOGE("perm_to_dac failed");
+ return ret;
+ }
}
-
+#ifdef SMACK_ENABLED
if (have_smack() && smack_accesses_apply(smack)) {
C_LOGE("smack_accesses_apply failed");
ret = PC_ERR_INVALID_OPERATION;
if (smack != NULL)
smack_accesses_free(smack);
free(smack_path);
+#endif //SMACK_ENABLED
return ret;
-#else
- return PC_OPERATION_SUCCESS;
-#endif
}
API int app_add_permissions(const char* app_id, const char** perm_list)
// TODO check process capabilities
// get feature file name
- ret = perm_file(app_type, api_feature_name, &feature_file);
+ ret = perm_file_path(&feature_file, app_type, api_feature_name, ".smack");
if (ret != PC_OPERATION_SUCCESS ) {
return ret;
}