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 C_LOGD("Enter function: %s", __func__);
66 element_t* new_element = malloc(sizeof(element_t));
67 if (NULL == new_element)
70 new_element->value = malloc(sizeof(char) * (SMACK_LABEL_LEN + 1) );
71 if (NULL == new_element->value) {
76 strncpy(new_element->value, value, SMACK_LABEL_LEN);
77 new_element->value[SMACK_LABEL_LEN] = '\0';
78 new_element->next = NULL;
79 elem->next = new_element;
84 static int remove_list(element_t* first_elem)
86 C_LOGD("Enter function: %s", __func__);
88 element_t* current = NULL;
90 while (NULL != first_elem) {
92 first_elem = first_elem->next;
98 static int add_id_to_database_internal(const char * id, db_app_type_t app_type)
100 C_LOGD("Enter function: %s", __func__);
101 FILE* file_db AUTO_FCLOSE;
102 const char* db_file_name = db_file_names[app_type];
104 file_db = fopen(db_file_name, "a");
105 if (NULL == file_db) {
106 C_LOGE("Error while opening database file: %s", db_file_name);
107 return PC_ERR_FILE_OPERATION;
110 if (0 > fprintf(file_db, "%s\n", id)) {
111 C_LOGE("Write label %s to database failed: %s", id, strerror(errno));
112 return PC_ERR_FILE_OPERATION;
115 return PC_OPERATION_SUCCESS;
118 static int get_all_ids_internal (char *** ids, int * len, db_app_type_t app_type)
121 char* scanf_label_format AUTO_FREE;
122 FILE* file_db AUTO_FCLOSE;
123 const char* db_file_name = db_file_names[app_type];
124 char smack_label[SMACK_LABEL_LEN + 1];
125 element_t* begin_of_list = NULL;
127 if (asprintf(&scanf_label_format, "%%%ds\\n", SMACK_LABEL_LEN) < 0) {
128 C_LOGE("Error while creating scanf input label format");
129 ret = PC_ERR_MEM_OPERATION;
133 file_db = fopen(db_file_name, "r");
134 if (NULL == file_db) {
135 C_LOGE("Error while opening antivirus_ids database file: %s", db_file_name);
136 ret = PC_ERR_FILE_OPERATION;
140 // intialization of list of smack labels
142 begin_of_list = malloc(sizeof(element_t));
143 if (begin_of_list == NULL ) {
144 C_LOGE("Error while allocating memory");
145 ret = PC_ERR_MEM_OPERATION;
148 begin_of_list->next = NULL;
149 begin_of_list->value = NULL;
150 element_t* current = begin_of_list;
152 // reading from file ("database")
153 // notice that first element always stays with empty "value"
154 while (fscanf(file_db, scanf_label_format, smack_label) == 1) {
155 smack_label[SMACK_LABEL_LEN] = '\0';
156 if (!smack_label_is_valid(smack_label)) {
157 C_LOGD("Found entry in database, but it's not correct SMACK label: \"%s\"", smack_label);
160 C_LOGD("Found installed anti virus label: \"%s\"", smack_label);
162 current = add_element(current, smack_label);
163 if (NULL == current) {
164 C_LOGE("Error while adding smack label to the list");
165 ret = PC_ERR_MEM_OPERATION;
171 C_LOGD("Allocating memory for list of %d labels", *len);
172 *ids = malloc((*len) * sizeof(char*));
174 C_LOGE("Error while allocating memory for list of labels");
175 ret = PC_ERR_MEM_OPERATION;
178 current = begin_of_list->next;
180 for (i=0; i < *len; ++i) {
181 C_LOGD("Allocating memory for \"%s\" label", current->value);
182 (*ids)[i] = malloc((SMACK_LABEL_LEN + 1) * sizeof(char));
183 if (NULL == (*ids)[i]) {
184 ret = PC_ERR_MEM_OPERATION;
185 C_LOGE("Error while allocating memory for \"%s\" label", current->value);
188 strncpy((*ids)[i], current->value, SMACK_LABEL_LEN);
189 (*ids)[i][SMACK_LABEL_LEN] = '\0';
190 current = current->next;
194 C_LOGD("Not found any labels!");
198 ret = PC_OPERATION_SUCCESS;
202 remove_list(begin_of_list);
207 int get_all_apps_ids (char *** apps_ids, int * len)
209 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_APPLICATION))
210 return PC_ERR_DB_OPERATION;
212 return PC_OPERATION_SUCCESS;
215 int get_all_settings_dir_ids(char ***apps_ids, int *len)
217 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_SETTING_DIR))
218 return PC_ERR_DB_OPERATION;
220 return PC_OPERATION_SUCCESS;
223 int get_all_appsetting_ids(char ***apps_ids, int *len)
225 if (get_all_ids_internal(apps_ids, len, DB_APP_TYPE_APPSETTING))
226 return PC_ERR_DB_OPERATION;
228 return PC_OPERATION_SUCCESS;
231 int get_all_avs_ids (char *** av_ids, int * len)
233 if (get_all_ids_internal(av_ids, len, DB_APP_TYPE_ANTIVIRUS))
234 return PC_ERR_DB_OPERATION;
236 return PC_OPERATION_SUCCESS;
239 int add_app_id_to_databse(const char * app_id)
241 C_LOGD("Enter function: %s", __func__);
243 if (add_id_to_database_internal(app_id, DB_APP_TYPE_APPLICATION))
244 return PC_ERR_DB_OPERATION;
246 return PC_OPERATION_SUCCESS;
249 int add_av_id_to_databse (const char * av_id)
251 C_LOGD("Enter function: %s", __func__);
253 if (add_id_to_database_internal(av_id, DB_APP_TYPE_ANTIVIRUS))
254 return PC_ERR_DB_OPERATION;
256 return PC_OPERATION_SUCCESS;
259 int add_appsetting_id_to_databse(const char *appsetting_id)
261 C_LOGD("Enter function: %s", __func__);
263 if (add_id_to_database_internal(appsetting_id, DB_APP_TYPE_APPSETTING))
264 return PC_ERR_DB_OPERATION;
266 return PC_OPERATION_SUCCESS;
269 int add_setting_dir_id_to_databse(const char *setting_dir_id)
271 C_LOGD("Enter function: %s", __func__);
273 if (add_id_to_database_internal(
274 setting_dir_id, DB_APP_TYPE_SETTING_DIR))
275 return PC_ERR_DB_OPERATION;
277 return PC_OPERATION_SUCCESS;
280 int add_app_gid(const char *app_id, unsigned gid)
282 C_LOGD("Enter function: %s", __func__);
286 ret = asprintf(&field, "%u:%s", gid, app_id);
288 return PC_ERR_MEM_OPERATION;
290 ret = add_id_to_database_internal(field, DB_APP_TYPE_GROUPS);
296 int get_app_gids(const char *app_id, unsigned **gids, int *len)
298 char** fields AUTO_FREE;
301 ret = get_all_ids_internal(&fields, &len_tmp, DB_APP_TYPE_GROUPS);
302 if (ret != PC_OPERATION_SUCCESS)
307 for (i = 0; i < len_tmp; ++i) {
308 const char *field = fields[i];
309 const char *app_id_tmp = NULL;
312 for (; *field; ++field) {
314 app_id_tmp = field + 1;
317 if (isdigit(*field)) {
318 gid = gid * 10 + *field - '0';
320 C_LOGE("Invalid line read: %s", fields[i]);
321 ret = PC_ERR_FILE_OPERATION;
327 C_LOGE("No group id found");
328 ret = PC_ERR_FILE_OPERATION;
332 if (!strcmp(app_id, app_id_tmp)) {
333 unsigned *gids_realloc = realloc(*gids, sizeof(unsigned) * (*len + 1));
334 if (gids_realloc == NULL) {
335 C_LOGE("Memory allocation failed");
336 ret = PC_ERR_MEM_OPERATION;
339 *gids = gids_realloc;
340 (*gids)[(*len)++] = gid;
344 ret = PC_OPERATION_SUCCESS;
346 for (i = 0; i < len_tmp; ++i)
349 if (ret != PC_OPERATION_SUCCESS) {
357 int db_add_public_dir(const char *dir_label)
359 C_LOGD("Enter function: %s", __func__);
361 if (add_id_to_database_internal(dir_label, DB_APP_TYPE_PUBLIC_DIRS))
362 return PC_ERR_DB_OPERATION;
364 return PC_OPERATION_SUCCESS;
367 int db_get_public_dirs(char ***dir_labels, int *len)
369 C_LOGD("Enter function: %s", __func__);
371 if (get_all_ids_internal(dir_labels, len, DB_APP_TYPE_PUBLIC_DIRS))
372 return PC_ERR_DB_OPERATION;
374 return PC_OPERATION_SUCCESS;