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"
37 DB_APP_TYPE_COUNT /* Dummy enum element to get number of elements */
40 const char* db_file_names[DB_APP_TYPE_COUNT] = {
41 "/opt/dbspace/.privilege_control_app_gids.db"
44 typedef struct element_s {
45 struct element_s* next;
49 static element_t* add_element (element_t* elem, const char* value)
51 SECURE_C_LOGD("Entering function: %s. Params: value=%s",
57 element_t* new_element = malloc(sizeof(element_t));
58 if (NULL == new_element)
61 new_element->value = malloc(sizeof(char) * (SMACK_LABEL_LEN + 1) );
62 if (NULL == new_element->value) {
67 strncpy(new_element->value, value, SMACK_LABEL_LEN);
68 new_element->value[SMACK_LABEL_LEN] = '\0';
69 new_element->next = NULL;
70 elem->next = new_element;
76 static int remove_list(element_t* first_elem)
78 SECURE_C_LOGD("Entering function: %s.", __func__);
80 element_t* current = NULL;
82 while (NULL != first_elem) {
84 first_elem = first_elem->next;
93 static int add_id_to_database_internal(const char * id, db_app_type_t app_type)
95 SECURE_C_LOGD("Entering function: %s. Params: id=%s",
98 FILE* file_db AUTO_FCLOSE;
99 const char* db_file_name = db_file_names[app_type];
101 SECURE_C_LOGD("Opening database file %s.", db_file_name);
102 file_db = fopen(db_file_name, "a");
103 if (NULL == file_db) {
104 SECURE_C_LOGD("Error while opening database file: %s", db_file_name);
105 return PC_ERR_FILE_OPERATION;
108 if (0 > fprintf(file_db, "%s\n", id)) {
109 SECURE_C_LOGE("Write label %s to database failed (error: %s)", id, strerror(errno));
110 return PC_ERR_FILE_OPERATION;
113 return PC_OPERATION_SUCCESS;
117 static int get_all_ids_internal (char *** ids, int * len, db_app_type_t app_type)
119 SECURE_C_LOGD("Entering function: %s.", __func__);
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 SECURE_C_LOGD("Opening database file %s.", db_file_name);
128 file_db = fopen(db_file_name, "r");
129 if (NULL == file_db) {
130 SECURE_C_LOGE("Error while opening database file: %s", db_file_name);
131 ret = PC_ERR_FILE_OPERATION;
135 // intialization of list of smack labels
137 begin_of_list = malloc(sizeof(element_t));
138 if (begin_of_list == NULL ) {
139 C_LOGE("Error while allocating memory");
140 ret = PC_ERR_MEM_OPERATION;
143 begin_of_list->next = NULL;
144 begin_of_list->value = NULL;
145 element_t* current = begin_of_list;
147 // reading from file ("database")
148 // notice that first element always stays with empty "value"
149 while (fscanf(file_db, "%" TOSTRING(SMACK_LABEL_LEN) "s\n", smack_label) == 1) {
150 smack_label[SMACK_LABEL_LEN] = '\0';
151 if (!smack_label_is_valid(smack_label)) {
152 SECURE_C_LOGD("Found entry in database, but it's not correct SMACK label: \"%s\"", smack_label);
155 SECURE_C_LOGD("Found installed label: \"%s\"", smack_label);
157 current = add_element(current, smack_label);
158 if (NULL == current) {
160 C_LOGE("Error while adding smack label to the list.");
161 ret = PC_ERR_MEM_OPERATION;
167 C_LOGD("Allocating memory for list of %d labels", *len);
168 *ids = malloc((*len) * sizeof(char*));
171 C_LOGE("Error while allocating memory for list of labels.");
172 ret = PC_ERR_MEM_OPERATION;
175 current = begin_of_list->next;
177 for (i=0; i < *len; ++i) {
178 C_LOGD("Allocating memory for \"%s\" label", current->value);
179 (*ids)[i] = malloc((SMACK_LABEL_LEN + 1) * sizeof(char));
180 if (NULL == (*ids)[i]) {
181 ret = PC_ERR_MEM_OPERATION;
183 for (j = 0; j < i; ++j)
188 C_LOGE("Error while allocating memory for \"%s\" label", current->value);
191 strncpy((*ids)[i], current->value, SMACK_LABEL_LEN);
192 (*ids)[i][SMACK_LABEL_LEN] = '\0';
193 current = current->next;
197 C_LOGD("No labels found!");
201 ret = PC_OPERATION_SUCCESS;
205 remove_list(begin_of_list);
211 int add_app_gid(const char *app_id, unsigned gid)
213 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, gid=%u",
214 __func__, app_id, gid);
219 ret = asprintf(&field, "%u:%s", gid, app_id);
222 C_LOGE("asprintf failed.");
223 return PC_ERR_MEM_OPERATION;
226 ret = add_id_to_database_internal(field, DB_APP_TYPE_GROUPS);
233 int get_app_gids(const char *app_id, unsigned **gids, int *len)
235 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
238 char** fields AUTO_FREE;
241 ret = get_all_ids_internal(&fields, &len_tmp, DB_APP_TYPE_GROUPS);
242 if (ret != PC_OPERATION_SUCCESS)
244 C_LOGE("get_all_ids_internal failed.");
250 for (i = 0; i < len_tmp; ++i) {
251 const char *field = fields[i];
252 const char *app_id_tmp = NULL;
255 for (; *field; ++field) {
257 app_id_tmp = field + 1;
260 if (isdigit(*field)) {
261 gid = gid * 10 + *field - '0';
263 C_LOGE("Invalid format of group id read from groups database: %s", fields[i]);
264 ret = PC_ERR_FILE_OPERATION;
270 C_LOGE("No group id found.");
271 ret = PC_ERR_FILE_OPERATION;
275 if (NULL == app_id) {
277 return PC_OPERATION_SUCCESS;
280 if (!strcmp(app_id, app_id_tmp)) {
281 unsigned *gids_realloc = realloc(*gids, sizeof(unsigned) * (*len + 1));
282 if (gids_realloc == NULL) {
283 C_LOGE("Memory allocation failed.");
284 ret = PC_ERR_MEM_OPERATION;
287 *gids = gids_realloc;
288 (*gids)[(*len)++] = gid;
292 ret = PC_OPERATION_SUCCESS;
294 for (i = 0; i < len_tmp; ++i)
297 if (ret != PC_OPERATION_SUCCESS) {