2 * libprivilege control, rules database
4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Jan Olszak <j.olszak@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.
23 * @file api_feature_loader.c
24 * @author Jan Olszak (j.olszak@samsung.com)
26 * @brief Binary file for loading predefined API features to the database.
30 #include <dirent.h> // For iterating directories
31 #include <getopt.h> // For getopt
32 #include <glob.h> // For glob
33 #include <obstack.h> // For obstack implementation
34 #include <privilege-control.h> // For app_type
35 #include <stdio.h> // For file manipulation
36 #include <stdlib.h> // For malloc and free
37 #include <sys/smack.h> // For SMACK_LABEL_LEN
38 #include <unistd.h> // For basename
41 #define API_FEATURE_LOADER_VERSION "1.0"
42 #define API_FEATURES_DIR "/usr/share/privilege-control/"
43 #define API_FEATURE_LOADER_LOG(format, ...) if(i_verbose_flag__) printf(format, ##__VA_ARGS__)
45 // Obstack configuration
46 #define obstack_chunk_alloc malloc
47 #define obstack_chunk_free free
48 #define vector_init(V) obstack_init(&(V))
49 #define vector_push_back_ptr(V, I) obstack_ptr_grow(&(V), (I))
50 #define vector_finish(V) obstack_finish(&(V))
51 #define vector_free(V) obstack_free(&(V), NULL)
52 typedef struct obstack vector_t;
54 static int i_verbose_flag__ = 0;
55 static const size_t ui_smack_ext_len__ = 6; // = strlen(".smack");
57 bool has_prefix(const char *const s_str, const char *const s_prefix)
59 return !strncmp(s_str, s_prefix, strlen(s_prefix));
62 bool has_smack_ext(const char *const s_str)
64 return strlen(s_str) > ui_smack_ext_len__ &&
65 !strncmp(&s_str[strlen(s_str) - ui_smack_ext_len__], ".smack", ui_smack_ext_len__);
68 int wrt_filter(const struct dirent *entry)
70 return !strcmp(entry->d_name, "WRT.smack");
73 int wrt_family_filter(const struct dirent *entry)
75 return has_prefix(entry->d_name, "WRT_") &&
76 has_smack_ext(entry->d_name);
79 int osp_filter(const struct dirent *entry)
81 return !strcmp(entry->d_name, "OSP.smack");
85 int osp_family_filter(const struct dirent *entry)
87 return has_prefix(entry->d_name, "OSP_") &&
88 has_smack_ext(entry->d_name);
91 int efl_filter(const struct dirent *entry)
93 return !strcmp(entry->d_name, "EFL.smack");
96 int efl_family_filter(const struct dirent *entry)
98 return has_prefix(entry->d_name, "EFL_") &&
99 has_smack_ext(entry->d_name);
102 void load_rules_from_file(const char *s_rules_file_path,
103 const char *s_permission_name,
104 const app_type_t app_type)
108 char **rules_array = NULL;
109 size_t i_num_rules = 0;
112 vector_t rules_vector;
114 p_file = fopen(s_rules_file_path, "r");
115 if(!p_file) goto finish;
117 API_FEATURE_LOADER_LOG("Loading permission: %s \n", s_permission_name);
119 vector_init(rules_vector);
120 while(getline(&s_rule, &i, p_file) > 0) {
121 vector_push_back_ptr(rules_vector, s_rule);
125 vector_push_back_ptr(rules_vector, NULL);
127 rules_array = vector_finish(rules_vector);
129 ret = perm_add_api_feature(app_type,
131 (const char **)rules_array,
134 if(ret != PC_OPERATION_SUCCESS)
135 API_FEATURE_LOADER_LOG("Error %d\n", ret);
138 if(p_file != NULL) fclose(p_file);
139 if(rules_array != NULL) {
140 for(i = 0; i < i_num_rules; ++i) {
141 free(rules_array[i]);
143 vector_free(rules_vector);
148 char *get_permission_name(const char *s_file_name, const char *s_prefix)
150 int i_prefix_len = strlen(s_prefix);
153 int i_perm_name_len = strlen(s_file_name);
154 char *s_permission_name = (char *) malloc(i_perm_name_len);
155 if(!s_permission_name) {
156 API_FEATURE_LOADER_LOG("Error during allocating memory.\n");
160 strncpy(s_permission_name,
161 &(s_file_name[i_prefix_len]),
162 i_perm_name_len - i_prefix_len - ui_smack_ext_len__);
164 s_permission_name[i_perm_name_len - i_prefix_len - ui_smack_ext_len__ ] = '\0';
166 return s_permission_name;
169 void load_permission_family(int (*filter)(const struct dirent *),
170 const char const *s_prefix,
171 const app_type_t app_type,
172 const char const *s_dir)
174 int i, num_files = 0;
175 struct dirent **file_list = NULL;
177 char *s_permission_name = NULL;
180 num_files = scandir(s_dir, &file_list, filter, alphasort);
181 for(i = 0; i < num_files; ++i) {
182 if(asprintf(&s_path, "%s%s", s_dir, file_list[i]->d_name) <= 0) continue;
184 s_permission_name = get_permission_name(file_list[i]->d_name, s_prefix);
185 load_rules_from_file(s_path, s_permission_name, app_type);
189 free(s_permission_name);
191 s_permission_name = NULL;
196 void load_pemission_type_rules(int (*filter)(const struct dirent *),
197 const char const *s_permission_name,
198 const app_type_t app_type,
199 const char const *s_dir)
202 struct dirent **file_list = NULL;
205 num_files = scandir(s_dir, &file_list, filter, alphasort);
206 for(i = 0; i < num_files; ++i) {
207 if(asprintf(&s_path, "%s%s", API_FEATURES_DIR, file_list[i]->d_name) <= 0) continue;
209 load_rules_from_file(s_path, s_permission_name, app_type);
219 void load_from_dir(const char *const s_dir)
222 API_FEATURE_LOADER_LOG("Loading rules from directory...\n");
223 if(perm_begin()) return;
225 // Load rules specific to permission's types:
226 load_pemission_type_rules(wrt_filter, "WRT", APP_TYPE_WGT, s_dir);
227 load_pemission_type_rules(osp_filter, "OSP", APP_TYPE_OSP, s_dir);
228 load_pemission_type_rules(efl_filter, "EFL", APP_TYPE_EFL, s_dir);
230 // Load rules for each permission type:
231 load_permission_family(wrt_family_filter, "WRT_", APP_TYPE_WGT, s_dir);
232 load_permission_family(osp_family_filter, "OSP_", APP_TYPE_OSP, s_dir);
233 load_permission_family(efl_family_filter, "EFL_", APP_TYPE_EFL, s_dir);
237 API_FEATURE_LOADER_LOG("Done.\n");
240 void load_single_file(const char *const s_file_path)
242 API_FEATURE_LOADER_LOG("Loading rules from file...\n");
243 if(perm_begin()) return;
245 char *s_permission_name = NULL;
249 if(!has_smack_ext(s_file_path)) {
250 API_FEATURE_LOADER_LOG("File doesn't have smack extension: %s\n", s_file_path);
255 s_file_name = basename(s_file_path);
256 strncpy(file.d_name, s_file_name, sizeof(file.d_name));
258 // Load as the right type of permission
259 if(wrt_family_filter(&file)) {
260 s_permission_name = get_permission_name(s_file_name, "WRT_");
261 load_rules_from_file(s_file_path, s_permission_name, APP_TYPE_WGT);
263 } else if(osp_family_filter(&file)) {
264 s_permission_name = get_permission_name(s_file_name, "OSP_");
265 load_rules_from_file(s_file_path, s_permission_name, APP_TYPE_OSP);
267 } else if(efl_family_filter(&file)) {
268 s_permission_name = get_permission_name(s_file_name, "EFL_");
269 load_rules_from_file(s_file_path, s_permission_name, APP_TYPE_EFL);
272 API_FEATURE_LOADER_LOG("Unknown api-feature type: %s\n", s_file_path);
275 free(s_permission_name);
278 API_FEATURE_LOADER_LOG("Done.\n");
281 void load_from_file(const char *const s_name_pattern)
283 API_FEATURE_LOADER_LOG("Loading rules from file(s) matching pattern: %s\n",
287 ret = glob(s_name_pattern, 0, NULL, &g);
289 if(ret == GLOB_ABORTED) {
290 API_FEATURE_LOADER_LOG("Cannot open given directory\n");
293 if(ret == GLOB_NOMATCH) {
294 API_FEATURE_LOADER_LOG("No match found for given pattern\n");
297 if(ret == GLOB_NOSPACE) {
298 API_FEATURE_LOADER_LOG("Not enough memory\n");
302 API_FEATURE_LOADER_LOG("Error during file(s) loading\n");
307 for(i = 0; i < g.gl_pathc; ++i)
308 load_single_file(g.gl_pathv[i]);
313 API_FEATURE_LOADER_LOG("Loading rules from file(s) matching pattern: %s done.\n",
317 int main(int argc, char *argv[])
320 int i_option_index = 0;
322 bool b_load_from_file = false;
323 const char *s_file_name = NULL;
325 bool b_load_from_dir = false;
326 const char *s_dir_name = NULL;
328 static struct option long_options[] = {
329 {"verbose", no_argument, &i_verbose_flag__, 1},
330 {"file", required_argument, 0, 'f'},
331 {"dir", required_argument, 0, 'd'},
332 {"help", no_argument, 0, 'h'},
333 {"version", no_argument, 0, 'v'},
337 while((c = getopt_long(argc, argv,
340 &i_option_index)) != -1) {
343 // If this option set a flag, do nothing.
347 // getopt_long already printed an error message.
350 b_load_from_file = true;
351 s_file_name = optarg;
355 b_load_from_dir = true;
360 printf("Api feature loader v." API_FEATURE_LOADER_VERSION "\n\n");
361 printf(" Options:\n");
362 printf(" -d,--dir=path load api-features from the directory\n");
363 printf(" -f,--file=file_name load api-feature from the file\n");
364 printf(" -h,--help print this help\n");
365 printf(" --verbose verbose output\n");
366 printf(" -v,--version show applcation version\n");
371 printf("Api feature loader v." API_FEATURE_LOADER_VERSION "\n");
379 // Print unknown remaining command line arguments
381 printf("Unknown options: ");
383 printf("%s ", argv[optind++]);
390 load_from_dir(s_dir_name);
392 load_from_file(s_file_name);
393 if(!b_load_from_dir &&
395 load_from_dir(API_FEATURES_DIR);