4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Janusz Kozerski <j.kozerski@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <sys/smack.h>
31 #include "access-db.h"
32 #include "privilege-control.h"
36 DB_APP_TYPE_APPLICATION,
37 DB_APP_TYPE_ANTIVIRUS,
39 DB_APP_TYPE_PUBLIC_DIRS,
40 DB_APP_TYPE_APPSETTING,
41 DB_APP_TYPE_SETTING_DIR,
42 DB_APP_TYPE_COUNT /* Dummy enum element to get number of elements */
45 const char* db_file_names[DB_APP_TYPE_COUNT] = {
46 "/opt/dbspace/.privilege_control_all_apps_id.db",
47 "/opt/dbspace/.privilege_control_all_avs_id.db",
48 "/opt/dbspace/.privilege_control_app_gids.db",
49 "/opt/dbspace/.privilege_control_public_dirs.db",
50 "/opt/dbspace/.privilege_control_app_setting.db",
51 "/opt/dbspace/.privilege_control_setting_dir.db",
54 typedef struct element_s {
55 struct element_s* next;
59 static element_t* add_element (element_t* elem, const char* value)
61 SECURE_C_LOGD("Entering function: %s. Params: value=%s",
67 element_t* new_element = malloc(sizeof(element_t));
68 if (NULL == new_element)
71 new_element->value = malloc(sizeof(char) * (SMACK_LABEL_LEN + 1) );
72 if (NULL == new_element->value) {
77 strncpy(new_element->value, value, SMACK_LABEL_LEN);
78 new_element->value[SMACK_LABEL_LEN] = '\0';
79 new_element->next = NULL;
80 elem->next = new_element;
85 static int remove_list(element_t* first_elem)
87 SECURE_C_LOGD("Entering function: %s.", __func__);
89 element_t* current = NULL;
91 while (NULL != first_elem) {
93 first_elem = first_elem->next;
101 static int add_id_to_database_internal(const char * id, db_app_type_t app_type)
103 SECURE_C_LOGD("Entering function: %s. Params: id=%s",
106 FILE* file_db AUTO_FCLOSE;
107 const char* db_file_name = db_file_names[app_type];
109 SECURE_C_LOGD("Opening database file %s.", db_file_name);
110 file_db = fopen(db_file_name, "a");
111 if (NULL == file_db) {
112 SECURE_C_LOGE("Error while opening database file: %s", db_file_name);
113 return PC_ERR_FILE_OPERATION;
116 if (0 > fprintf(file_db, "%s\n", id)) {
117 SECURE_C_LOGE("Write label %s to database failed (error: %s)", id, strerror(errno));
118 return PC_ERR_FILE_OPERATION;
121 return PC_OPERATION_SUCCESS;
124 static int get_all_ids_internal (char *** ids, int * len, db_app_type_t app_type)
126 SECURE_C_LOGD("Entering function: %s.", __func__);
129 FILE* file_db AUTO_FCLOSE;
130 const char* db_file_name = db_file_names[app_type];
131 char smack_label[SMACK_LABEL_LEN + 1];
132 element_t* begin_of_list = NULL;
134 SECURE_C_LOGD("Opening database file %s.", db_file_name);
135 file_db = fopen(db_file_name, "r");
136 if (NULL == file_db) {
137 SECURE_C_LOGE("Error while opening database file: %s", db_file_name);
138 ret = PC_ERR_FILE_OPERATION;
142 // intialization of list of smack labels
144 begin_of_list = malloc(sizeof(element_t));
145 if (begin_of_list == NULL ) {
146 C_LOGE("Error while allocating memory");
147 ret = PC_ERR_MEM_OPERATION;
150 begin_of_list->next = NULL;
151 begin_of_list->value = NULL;
152 element_t* current = begin_of_list;
154 // reading from file ("database")
155 // notice that first element always stays with empty "value"
156 while (fscanf(file_db, "%" TOSTRING(SMACK_LABEL_LEN) "s\n", smack_label) == 1) {
157 smack_label[SMACK_LABEL_LEN] = '\0';
158 if (!smack_label_is_valid(smack_label)) {
159 SECURE_C_LOGD("Found entry in database, but it's not correct SMACK label: \"%s\"", smack_label);
162 SECURE_C_LOGD("Found installed label: \"%s\"", smack_label);
164 current = add_element(current, smack_label);
165 if (NULL == current) {
167 C_LOGE("Error while adding smack label to the list.");
168 ret = PC_ERR_MEM_OPERATION;
174 C_LOGD("Allocating memory for list of %d labels", *len);
175 *ids = malloc((*len) * sizeof(char*));
178 C_LOGE("Error while allocating memory for list of labels.");
179 ret = PC_ERR_MEM_OPERATION;
182 current = begin_of_list->next;
184 for (i=0; i < *len; ++i) {
185 C_LOGD("Allocating memory for \"%s\" label", current->value);
186 (*ids)[i] = malloc((SMACK_LABEL_LEN + 1) * sizeof(char));
187 if (NULL == (*ids)[i]) {
188 ret = PC_ERR_MEM_OPERATION;
190 for (j = 0; j < i; ++j)
195 C_LOGE("Error while allocating memory for \"%s\" label", current->value);
198 strncpy((*ids)[i], current->value, SMACK_LABEL_LEN);
199 (*ids)[i][SMACK_LABEL_LEN] = '\0';
200 current = current->next;
204 C_LOGD("No labels found!");
208 ret = PC_OPERATION_SUCCESS;
212 remove_list(begin_of_list);
217 int get_all_apps_ids (char *** apps_ids, int * len)
219 SECURE_C_LOGD("Entering function: %s.", __func__);
221 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_APPLICATION))
222 return PC_ERR_DB_OPERATION;
224 return PC_OPERATION_SUCCESS;
227 int get_all_settings_dir_ids(char ***apps_ids, int *len)
229 SECURE_C_LOGD("Entering function: %s.", __func__);
231 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_SETTING_DIR))
232 return PC_ERR_DB_OPERATION;
234 return PC_OPERATION_SUCCESS;
237 int get_all_appsetting_ids(char ***apps_ids, int *len)
239 SECURE_C_LOGD("Entering function: %s.", __func__);
241 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_APPSETTING))
242 return PC_ERR_DB_OPERATION;
244 return PC_OPERATION_SUCCESS;
247 int get_all_avs_ids (char *** av_ids, int * len)
249 SECURE_C_LOGD("Entering function: %s.", __func__);
251 if (get_all_ids_internal(av_ids, len, DB_APP_TYPE_ANTIVIRUS))
252 return PC_ERR_DB_OPERATION;
254 return PC_OPERATION_SUCCESS;
257 int add_app_id_to_databse(const char * app_id)
259 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
262 if (add_id_to_database_internal(app_id, DB_APP_TYPE_APPLICATION))
263 return PC_ERR_DB_OPERATION;
265 return PC_OPERATION_SUCCESS;
268 int add_av_id_to_databse (const char * av_id)
270 SECURE_C_LOGD("Entering function: %s. Params: av_id=%s",
273 if (add_id_to_database_internal(av_id, DB_APP_TYPE_ANTIVIRUS))
274 return PC_ERR_DB_OPERATION;
276 return PC_OPERATION_SUCCESS;
279 int add_appsetting_id_to_databse(const char *appsetting_id)
281 SECURE_C_LOGD("Entering function: %s. Params: appsetting_id=%s",
282 __func__, appsetting_id);
284 if (add_id_to_database_internal(appsetting_id, DB_APP_TYPE_APPSETTING))
285 return PC_ERR_DB_OPERATION;
287 return PC_OPERATION_SUCCESS;
290 int add_setting_dir_id_to_databse(const char *setting_dir_id)
292 SECURE_C_LOGD("Entering function: %s. Params: setting_dir_id=%s",
293 __func__, setting_dir_id);
295 if (add_id_to_database_internal(
296 setting_dir_id, DB_APP_TYPE_SETTING_DIR))
297 return PC_ERR_DB_OPERATION;
299 return PC_OPERATION_SUCCESS;
302 int add_app_gid(const char *app_id, unsigned gid)
304 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, gid=%u",
305 __func__, app_id, gid);
310 ret = asprintf(&field, "%u:%s", gid, app_id);
313 C_LOGE("asprintf failed.");
314 return PC_ERR_MEM_OPERATION;
317 ret = add_id_to_database_internal(field, DB_APP_TYPE_GROUPS);
323 int get_app_gids(const char *app_id, unsigned **gids, int *len)
325 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
328 char** fields AUTO_FREE;
331 ret = get_all_ids_internal(&fields, &len_tmp, DB_APP_TYPE_GROUPS);
332 if (ret != PC_OPERATION_SUCCESS)
334 C_LOGE("get_all_ids_internal failed.");
340 for (i = 0; i < len_tmp; ++i) {
341 const char *field = fields[i];
342 const char *app_id_tmp = NULL;
345 for (; *field; ++field) {
347 app_id_tmp = field + 1;
350 if (isdigit(*field)) {
351 gid = gid * 10 + *field - '0';
353 C_LOGE("Invalid format of group id read from groups database: %s", fields[i]);
354 ret = PC_ERR_FILE_OPERATION;
360 C_LOGE("No group id found.");
361 ret = PC_ERR_FILE_OPERATION;
365 if (NULL == app_id) {
367 return PC_OPERATION_SUCCESS;
370 if (!strcmp(app_id, app_id_tmp)) {
371 unsigned *gids_realloc = realloc(*gids, sizeof(unsigned) * (*len + 1));
372 if (gids_realloc == NULL) {
373 C_LOGE("Memory allocation failed.");
374 ret = PC_ERR_MEM_OPERATION;
377 *gids = gids_realloc;
378 (*gids)[(*len)++] = gid;
382 ret = PC_OPERATION_SUCCESS;
384 for (i = 0; i < len_tmp; ++i)
387 if (ret != PC_OPERATION_SUCCESS) {
395 int db_add_public_dir(const char *dir_label)
397 SECURE_C_LOGD("Entering function: %s. Params: dir_label=%s",
398 __func__, dir_label);
400 if (add_id_to_database_internal(dir_label, DB_APP_TYPE_PUBLIC_DIRS))
402 C_LOGE("add_id_to_database_internal failed.");
403 return PC_ERR_DB_OPERATION;
406 return PC_OPERATION_SUCCESS;
409 int db_get_public_dirs(char ***dir_labels, int *len)
411 SECURE_C_LOGD("Entering function: %s.", __func__);
413 if (get_all_ids_internal(dir_labels, len, DB_APP_TYPE_PUBLIC_DIRS))
415 C_LOGE("get_all_ids_internal failed.");
416 return PC_ERR_DB_OPERATION;
419 return PC_OPERATION_SUCCESS;