Remove unnecessary defines.
[platform/core/security/libprivilege-control.git] / src / privilege-control.c
1 /*
2  * libprivilege control
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact: Kidong Kim <kd0228.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #define _GNU_SOURCE
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <pwd.h>
29 #include <grp.h>
30 #include <fts.h>
31 #include <errno.h>
32 #include <math.h>
33 #include <ctype.h>
34 #include <fcntl.h>
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <sys/file.h>
38 #include <sys/smack.h>
39 #include <linux/capability.h>
40 #include <linux/xattr.h>
41 #include <sys/capability.h>
42 #include <sys/mman.h>
43 #include <stdbool.h>
44 #include <search.h>
45
46 #include "privilege-control.h"
47 #include "access-db.h"
48 #include "common.h"
49 #include "rules-db.h"
50
51 #define APP_GID 5000
52 #define APP_UID 5000
53 #define DEVELOPER_GID   5100
54 #define DEVELOPER_UID   5100
55
56 #define APP_USER_NAME   "app"
57 #define DEV_USER_NAME   "developer"
58
59 #define APP_HOME_DIR    TOSTRING(HOMEDIR) "/app"
60 #define DEV_HOME_DIR    TOSTRING(HOMEDIR) "/developer"
61
62 /* Macro defined below is used to label links to executables */
63 #define XATTR_NAME_TIZENEXEC XATTR_SECURITY_PREFIX "TIZEN_EXEC_LABEL"
64
65 typedef struct {
66         char user_name[10];
67         int uid;
68         int gid;
69         char home_dir[64];
70 } new_user;
71
72 /**
73  * Return values
74  * <0 - error
75  * 0 - skip
76  * 1 - label
77  */
78 typedef int (*label_decision_fn)(const FTSENT*);
79 enum {
80         DECISION_SKIP = 0,
81         DECISION_LABEL = 1
82 };
83
84 __attribute__ ((destructor))
85 static void libprivilege_destructor()
86 {
87         SECURE_C_LOGD("Entering function: %s.", __func__);
88         perm_end();
89 }
90
91 API int perm_begin(void)
92 {
93         SECURE_C_LOGD("Entering function: %s.", __func__);
94         return rdb_modification_start();
95 }
96
97 API int perm_end(void)
98 {
99         SECURE_C_LOGD("Entering function: %s.", __func__);
100
101         return rdb_modification_finish();
102 }
103
104 API int perm_rollback(void)
105 {
106         SECURE_C_LOGD("Entering function: %s.", __func__);
107
108         int ret = rdb_modification_rollback();
109
110         if (ret != PC_OPERATION_SUCCESS) {
111                 C_LOGE("RDB %s failed with: %d", __func__, ret);
112                 return ret;
113         }
114
115         return PC_OPERATION_SUCCESS;
116 }
117
118 API int control_privilege(void)//deprecated
119 {
120         SECURE_C_LOGD("Entering function: %s.", __func__);
121
122         if(getuid() == APP_UID) // current user is 'app'
123                 return PC_OPERATION_SUCCESS;
124
125         if(perm_app_set_privilege("org.tizen.", NULL, NULL) == PC_OPERATION_SUCCESS)
126                 return PC_OPERATION_SUCCESS;
127         else {
128                 C_LOGE("perm_app_set_privilege failed (not permitted).");
129                 return PC_ERR_NOT_PERMITTED;
130         }
131 }
132
133 static int get_user_groups(uid_t user_id, int *nbgroup, gid_t **groups_list)
134 {
135         gid_t *groups = NULL;
136         struct passwd * pw;
137         C_LOGD("Enter function: %s", __func__);
138
139         if ((!groups_list) || (!nbgroup))
140                 return PC_ERR_INVALID_OPERATION;
141         pw = getpwuid(user_id);
142         if(!pw) {
143                 C_LOGE("getgrouplist fails : Invalid User ID %d",user_id);
144                 return PC_ERR_INVALID_OPERATION;
145         }
146         *nbgroup = 0;
147         //First call is done with *ngroup = 0 to get the number of groups found for the user (Usefull for next malloc operation). It should return -1 in this case.
148         if (getgrouplist(pw->pw_name,  pw->pw_gid, groups, nbgroup) != -1)
149                 return PC_ERR_INVALID_OPERATION;
150
151         C_LOGD("getgrouplist %s user is member of %d groups ",pw->pw_name,*nbgroup);
152         groups = malloc(*nbgroup * sizeof (gid_t));
153         if (!groups)
154                 return PC_ERR_INVALID_OPERATION;
155         //Second call is done with the suitable ngroup value and structure groups allocated.
156         if (getgrouplist(pw->pw_name,  pw->pw_gid, groups, nbgroup) == -1) {
157                 free(groups);
158                 C_LOGE("getgrouplist fails %d",nbgroup);
159                 return PC_ERR_INVALID_OPERATION;
160         }
161         *groups_list = groups;
162         return  PC_OPERATION_SUCCESS;
163 }
164
165 static int set_dac(const char *smack_label, const char *pkg_name)
166 {
167         SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s, pkg_name=%s",
168                                 __func__, smack_label, pkg_name);
169
170         uid_t t_uid = -1;               // uid of current process
171         gid_t *glist = NULL;    // group list
172         int glist_cnt = 0;              // for group list
173         int result;
174         int i;
175         new_user usr;
176         unsigned *additional_gids = NULL;
177
178         /*
179          * initialize user structure
180          */
181         C_LOGD("Initialize user structure");
182         memset(usr.user_name, 0x00, 10);
183         memset(usr.home_dir, 0x00, 64);
184         usr.uid = -1;
185         usr.gid = -1;
186
187         t_uid = getuid();
188         C_LOGD("Current uid is %d", t_uid);
189
190         if(t_uid == 0)  // current user is 'root'
191         {
192                 if(!strncmp(pkg_name, "developer", 9))
193                 {
194                         strncpy(usr.user_name, DEV_USER_NAME, sizeof(usr.user_name));
195                         usr.uid = DEVELOPER_UID;
196                         usr.gid = DEVELOPER_GID;
197                         strncpy(usr.home_dir, DEV_HOME_DIR, sizeof(usr.home_dir));
198                 }
199                 else
200                 {
201                         strncpy(usr.user_name, APP_USER_NAME, sizeof(usr.user_name));
202                         usr.uid = APP_UID;
203                         usr.gid = APP_GID;
204                         strncpy(usr.home_dir, APP_HOME_DIR, sizeof(usr.home_dir));
205                 }
206
207                 /*
208                  * get group information
209                  */
210                 C_LOGD("get group information");
211                 if (get_user_groups(usr.uid, &glist_cnt, &glist)) {
212                         result = PC_ERR_FILE_OPERATION; // return -1
213                         goto error;
214                 }
215                 {
216                         gid_t *glist_new;
217                         int i, cnt;
218
219                         result = get_app_gids(smack_label, &additional_gids, &cnt);
220                         if (result != PC_OPERATION_SUCCESS)
221                                 goto error;
222
223                         if (cnt > 0) {
224                                 glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + cnt));
225                                 if (glist_new == NULL) {
226                                         result = PC_ERR_MEM_OPERATION;  // return -2
227                                         C_LOGE("Memory allocation failed");
228                                         goto error;
229                                 }
230                                 glist = glist_new;
231                                 for (i = 0; i < cnt; ++i) {
232                                         C_LOGD("Additional GID based on enabled permissions: %u", additional_gids[i]);
233                                         glist[glist_cnt++] = additional_gids[i];
234                                 }
235                         }
236                 }
237
238                 /*
239                  * setgroups()
240                  */
241                 C_LOGD("Adding process to the following groups:");
242                 for(i=0; i<glist_cnt; ++i) {
243                         SECURE_C_LOGD("glist [ %d ] = %d", i, glist[i]);
244                 }
245                 C_LOGD("Calling setgroups()");
246                 if(setgroups(glist_cnt, glist) != 0)
247                 {
248                         C_LOGE("setgroups failed");
249                         result = PC_ERR_NOT_PERMITTED;  // return -3
250                         goto error;
251                 }
252                 if(glist != NULL)
253                 {
254                         free(glist);
255                         glist = NULL;
256                 }
257
258                 /*
259                  * setuid() & setgid()
260                  */
261                 C_LOGD("setgid( %d ) & setuid( %d )", usr.gid, usr.uid);
262                 if(setgid(usr.gid) != 0)        // fail
263                 {
264                         C_LOGE("Failed to execute setgid().");
265                         result = PC_ERR_INVALID_OPERATION;
266                         goto error;
267                 }
268                 if(setuid(usr.uid) != 0)        // fail
269                 {
270                         C_LOGE("Failed to execute setuid().");
271                         result = PC_ERR_INVALID_OPERATION;
272                         goto error;
273                 }
274
275                 SECURE_C_LOGD("setenv(): USER = %s, HOME = %s", usr.user_name, usr.home_dir);
276                 if(setenv("USER", usr.user_name, 1) != 0)       //fail
277                 {
278                         C_LOGE("Failed to execute setenv() [USER].");
279                         result = PC_ERR_INVALID_OPERATION;
280                         goto error;
281                 }
282                 if(setenv("HOME", usr.home_dir, 1) != 0)        // fail
283                 {
284                         C_LOGE("Failed to execute setenv() [HOME].");
285                         result = PC_ERR_INVALID_OPERATION;
286                         goto error;
287                 }
288         }
289         else    // current user is not only 'root' but 'app'
290         {
291                 C_LOGE("Current user is NOT root");
292                 result = PC_ERR_NOT_PERMITTED;  // return -3
293                 goto error;
294         }
295
296         result = PC_OPERATION_SUCCESS;
297
298 error:
299         if(glist != NULL)
300                 free(glist);
301         free(additional_gids);
302
303         return result;
304 }
305
306 /**
307  * Get SMACK label from EXEC label of a file.
308  * SMACK label should be freed by caller
309  *
310  * @param path file path to take label from
311  * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
312  */
313 static int get_smack_from_binary(char **smack_label, const char* path)
314 {
315         SECURE_C_LOGD("Entering function: %s. Params: path=%s", __func__, path);
316         char value[SMACK_LABEL_LEN + 1];
317         int ret;
318
319         /* First try: check SMACKEXEC label on binary */
320         ret = getxattr(path, XATTR_NAME_SMACKEXEC, value, SMACK_LABEL_LEN + 1);
321         if (ret > 0)
322                 goto finalize;
323         if (errno != ENODATA)
324                 goto error;
325
326         /* Second try: check TIZENEXEC label on binary */
327         ret = getxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
328         if (ret > 0)
329                 goto finalize;
330         if (errno != ENODATA)
331                 goto error;
332
333         /* Third try: check TIZENEXEC label on symbolic link */
334         ret = lgetxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
335         if (ret > 0)
336                 goto finalize;
337         if (errno != ENODATA)
338                 goto error;
339
340         /* None of labels found  return NULL*/
341         *smack_label = NULL;
342         return PC_OPERATION_SUCCESS;
343
344 finalize:
345         /* Success! */
346         value[ret] = '\0';  /* because getxattr does not add 0 at the end! */
347         *smack_label = strdup(value);
348         if (*smack_label == NULL) {
349                 C_LOGE("Cannot allocate memory for smack_label");
350                 return PC_ERR_MEM_OPERATION;
351         }
352         return PC_OPERATION_SUCCESS;
353
354 error:
355         C_LOGE("Getting exec label from file %s failed", path);
356         return PC_ERR_INVALID_OPERATION;
357 }
358
359 /**
360  * Set process SMACK label.
361  * This function is emulating EXEC label behavior of SMACK for programs
362  * run by dlopen/dlsym instead of execv.
363  *
364  * @param smack label
365  * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
366  */
367 static int set_smack_for_self (char *smack_label)
368 {
369         SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s",
370                                 __func__, smack_label);
371         int ret;
372
373         if (smack_label == NULL) {
374                 /* No label to set, just return with success */
375                 C_LOGD("No label to set, just return with success.");
376                 ret = PC_OPERATION_SUCCESS;
377         }
378         else {
379                 SECURE_C_LOGD("smack_label=%s", smack_label);
380                 if (have_smack()) {
381                         ret = smack_set_label_for_self(smack_label);
382                         C_LOGD("smack_set_label_for_self returned %d", ret);
383                 } else
384                         ret = PC_OPERATION_SUCCESS;
385         }
386
387         return ret;
388 }
389
390 API int set_app_privilege(const char* name, const char* type, const char* path)//deprecated
391 {
392         SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
393                                 __func__, name, type, path);
394
395         return perm_app_set_privilege(name, type, path);
396 }
397
398 API int perm_app_set_privilege(const char* name, const char* type UNUSED, const char* path)
399 {
400         SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
401                                 __func__, name, type, path);
402
403         //SECURE_C_LOGD("Function params: name = %s, type = %s, path = %s", name, type, path);
404         int ret = PC_OPERATION_SUCCESS;
405         char *smack_label AUTO_FREE;
406
407         if (name == NULL) {
408                 C_LOGE("Error invalid parameter");
409                 return PC_ERR_INVALID_PARAM;
410         }
411
412         if (path != NULL && have_smack()) {
413                 ret = get_smack_from_binary(&smack_label, path);
414                 if (ret != PC_OPERATION_SUCCESS)
415                         return ret;
416
417                 ret = set_smack_for_self(smack_label);
418                 if (ret != PC_OPERATION_SUCCESS)
419                         return ret;
420         }
421
422         if (path != NULL && !have_smack()) {
423                 ret = get_smack_from_binary(&smack_label, path);
424                 if (ret != PC_OPERATION_SUCCESS)
425                         return ret;
426         }
427
428         return set_dac(smack_label, name);
429 }
430
431 API int set_privilege(const char* pkg_name)//deprecated
432 {
433         SECURE_C_LOGD("Entering function: %s. Params: pkg_name=%s",
434                                 __func__, pkg_name);
435
436         return perm_app_set_privilege(pkg_name, NULL, NULL);
437 }
438
439 static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix, bool is_early)
440 {
441         SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, perm=%s, suffix=%s, is_early=%d",
442                                 __func__, app_type, perm, suffix, is_early);
443
444         const char* app_type_prefix = NULL;
445         char* perm_basename = NULL;
446         int ret = 0;
447
448         if (perm == NULL || strlen(perm) == 0) {
449                 C_LOGE("Empty permission name.");
450                 return PC_ERR_INVALID_PARAM;
451         }
452
453         app_type_prefix = app_type_group_name(app_type);
454
455         ret = base_name_from_perm(perm, &perm_basename);
456         if (ret != PC_OPERATION_SUCCESS) {
457                 C_LOGE("Couldn't get permission basename.");
458                 return ret;
459         }
460
461         if (is_early) {
462                 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s%s",
463                 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
464                 perm_basename, "_early", suffix);
465         }
466         else {
467                 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
468                 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
469                 perm_basename, suffix);
470         }
471         if (ret == -1) {
472                 C_LOGE("asprintf failed.");
473                 return PC_ERR_MEM_OPERATION;
474         }
475
476         C_LOGD("Path=%s", *path);
477
478         return PC_OPERATION_SUCCESS;
479 }
480
481 static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
482 {
483         SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
484                                 __func__, app_label, app_type, perm);
485
486         int ret;
487         char* path AUTO_FREE;
488         FILE* file AUTO_FCLOSE;
489         int gid;
490
491         ret = perm_file_path(&path, app_type, perm, ".dac", 0);
492         if (ret != PC_OPERATION_SUCCESS) {
493                 C_LOGD("No dac config file for permission %s", perm);
494                 return ret;
495         }
496
497         SECURE_C_LOGD("Opening file %s.", path);
498         file = fopen(path, "r");
499         if (file == NULL) {
500                 C_LOGW("fopen failed.");
501                 return PC_OPERATION_SUCCESS;
502         }
503
504         while (fscanf(file, "%d\n", &gid) == 1) {
505                 SECURE_C_LOGD("Adding app_id %s to group %d", app_label, gid);
506                 ret = add_app_gid(app_label, gid);
507                 if (ret != PC_OPERATION_SUCCESS) {
508                         C_LOGE("add_app_gid failed");
509                         return ret;
510                 }
511         }
512
513         return PC_OPERATION_SUCCESS;
514 }
515
516 static int label_all(const FTSENT* ftsent UNUSED)
517 {
518         SECURE_C_LOGD("Entering function: %s.", __func__);
519
520         return DECISION_LABEL;
521 }
522
523 static int label_execs(const FTSENT* ftsent)
524 {
525         SECURE_C_LOGD("Entering function: %s.", __func__);
526
527         C_LOGD("Mode = %d", ftsent->fts_statp->st_mode);
528         // label only regular executable files
529         if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
530                 return DECISION_LABEL;
531         return DECISION_SKIP;
532 }
533
534 static int label_dirs(const FTSENT* ftsent)
535 {
536         SECURE_C_LOGD("Entering function: %s.", __func__);
537
538         // label only directories
539         if (S_ISDIR(ftsent->fts_statp->st_mode))
540                 return DECISION_LABEL;
541         return DECISION_SKIP;
542 }
543
544 static int label_links_to_execs(const FTSENT* ftsent)
545 {
546         SECURE_C_LOGD("Entering function: %s.", __func__);
547
548         struct stat buf;
549         char* target AUTO_FREE;
550
551         // check if it's a link
552         if ( !S_ISLNK(ftsent->fts_statp->st_mode))
553                 return DECISION_SKIP;
554
555         target = realpath(ftsent->fts_path, NULL);
556         if (!target) {
557                 SECURE_C_LOGE("Getting link target for %s failed (Error = %s)", ftsent->fts_path, strerror(errno));
558                 return PC_ERR_FILE_OPERATION;
559         }
560         if (-1 == stat(target, &buf)) {
561                 SECURE_C_LOGE("stat failed for %s (Error = %s", target, strerror(errno));
562                 return PC_ERR_FILE_OPERATION;
563         }
564         // skip if link target is not a regular executable file
565         if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
566                 SECURE_C_LOGD("%s is not a regular executable file. Skipping.", target);
567                 return DECISION_SKIP;
568         }
569
570         return DECISION_LABEL;
571 }
572
573 static int dir_set_smack_r(const char *path, const char* label,
574                            const char *xattr_name, label_decision_fn fn)
575 {
576         SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, xattr_name=%s",
577                                 __func__, path, label, xattr_name);
578
579         const char* path_argv[] = {path, NULL};
580         FTS *fts AUTO_FTS_CLOSE;
581         FTSENT *ftsent;
582         int ret;
583
584         int len = strnlen(label, SMACK_LABEL_LEN + 1);
585         if (len > SMACK_LABEL_LEN) {
586                 C_LOGE("parameter \"label\" is to long.");
587                 return PC_ERR_INVALID_PARAM;
588         }
589
590         fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
591         if (fts == NULL) {
592                 C_LOGE("fts_open failed.");
593                 return PC_ERR_FILE_OPERATION;
594         }
595
596         while ((ftsent = fts_read(fts)) != NULL) {
597                 /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
598                 if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
599                         C_LOGE("FTS_ERR error or failed stat(2) (FTS_NS)");
600                         return PC_ERR_FILE_OPERATION;
601                 }
602
603                 ret = fn(ftsent);
604                 if (ret < 0) {
605                         C_LOGE("fn(ftsent) failed.");
606                         return ret;
607                 }
608
609                 if (ret == DECISION_LABEL) {
610                         C_LOGD("lsetxattr (path: %s, xattr_name: %s, label: %s len: %d, 0",
611                                 ftsent->fts_path, xattr_name, label, len);
612
613                         if (lsetxattr(ftsent->fts_path, xattr_name, label, len, 0) != 0) {
614                                 C_LOGE("lsetxattr failed.");
615                                 return PC_ERR_FILE_OPERATION;
616                         }
617                 }
618         }
619
620         /* If last call to fts_read() set errno, we need to return error. */
621         if (errno != 0) {
622                 C_LOGE("Last errno from fts_read: %s", strerror(errno));
623                 return PC_ERR_FILE_OPERATION;
624         }
625         return PC_OPERATION_SUCCESS;
626 }
627 API char* app_id_from_socket(int sockfd)//deprecated
628 {
629         SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
630                                 __func__, sockfd);
631
632     return perm_app_id_from_socket(sockfd);
633 }
634
635 API char* perm_app_id_from_socket(int sockfd)
636 {
637         SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
638                                 __func__, sockfd);
639
640         if (!have_smack()) {
641                 C_LOGD("No SMACK. Returning NULL.");
642                 return NULL;
643         }
644
645         char* app_id;
646         int ret;
647
648         ret = smack_new_label_from_socket(sockfd, &app_id);
649         if (ret < 0) {
650                 C_LOGE("smack_new_label_from_socket failed");
651                 return NULL;
652         }
653
654         SECURE_C_LOGD("app_id = %s", app_id);
655
656         return app_id;
657 }
658
659
660 API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
661 {
662         SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
663                                 __func__, app_id);
664
665         return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, true);
666 }
667
668 API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
669 {
670         SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
671                                 __func__, app_id);
672
673         return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, false);
674 }
675
676 API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
677 {
678         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
679                                 __func__, pkg_id, app_type, persistent);
680
681         return perm_app_enable_permissions(pkg_id, app_type, perm_list, persistent);
682 }
683
684 API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type,
685                                     const char** perm_list, bool persistent)
686 {
687         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
688                                 __func__, pkg_id, app_type, persistent);
689
690         int i, ret;
691         const char *app_label AUTO_FREE;
692
693         if (!smack_label_is_valid(pkg_id)) {
694                 C_LOGE("Invalid param app_id.");
695                 return PC_ERR_INVALID_PARAM;
696         }
697
698         if (perm_list == NULL) {
699                 C_LOGE("Invalid perm_list (NULL).");
700                 return PC_ERR_INVALID_PARAM;
701         }
702
703         if (app_type_group_name(app_type) == NULL) {
704                 C_LOGE("Unknown app type.");
705                 return PC_ERR_INVALID_PARAM;
706         }
707
708         app_label = generate_app_label(pkg_id);
709         if (app_label == NULL) {
710                 C_LOGE("generate_app_label returned NULL.");
711                 return PC_ERR_MEM_OPERATION;
712         }
713
714         /* Add permission to DAC */
715         for (i = 0; perm_list[i] != NULL; ++i) {
716                 ret = perm_to_dac(pkg_id, app_type, perm_list[i]);
717                 if (ret != PC_OPERATION_SUCCESS) {
718                         C_LOGE("perm_to_dac failed");
719                         return ret;
720                 }
721         }
722
723         /* Enable the permissions: */
724         ret = rdb_enable_app_permissions(app_label, app_type, perm_list,
725                                          !((bool)persistent));
726         if (ret != PC_OPERATION_SUCCESS) {
727                 C_LOGE("RDB rdb_enable_app_permissions failed with: %d", ret);
728                 return ret;
729         }
730
731         return PC_OPERATION_SUCCESS;
732 }
733
734 API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
735 {
736         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
737                                 __func__, pkg_id, app_type);
738
739         return perm_app_disable_permissions(pkg_id, app_type, perm_list);
740 }
741
742 API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
743 {
744         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
745                                 __func__, pkg_id, app_type);
746
747         int ret;
748         const char *app_label AUTO_FREE;
749         if (!smack_label_is_valid(pkg_id)) {
750                 C_LOGE("Invalid param app_id.");
751                 return PC_ERR_INVALID_PARAM;
752         }
753
754         if (perm_list == NULL) {
755                 C_LOGE("Invalid perm_list (NULL).");
756                 return PC_ERR_INVALID_PARAM;
757         }
758
759         if (app_type_group_name(app_type) == NULL) {
760                 C_LOGE("Unknown app type.");
761                 return PC_ERR_INVALID_PARAM;
762         }
763
764         app_label = generate_app_label(pkg_id);
765         if (app_label == NULL) {
766                 C_LOGE("generate_app_label returned NULL.");
767                 return PC_ERR_MEM_OPERATION;
768         }
769
770         ret = rdb_disable_app_permissions(app_label, app_type, perm_list);
771         if (ret != PC_OPERATION_SUCCESS) {
772                 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
773                 return ret;
774         }
775
776         return PC_OPERATION_SUCCESS;
777 }
778
779 API int app_revoke_permissions(const char* pkg_id)//deprecated
780 {
781         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
782         return perm_app_revoke_permissions(pkg_id);
783 }
784
785 API int perm_app_revoke_permissions(const char* pkg_id)
786 {
787         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
788         /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
789         /*int ret;
790         const char *app_label AUTO_FREE;*/
791
792         if (!smack_label_is_valid(pkg_id)) {
793                 C_LOGE("Invalid param app_id.");
794                 return PC_ERR_INVALID_PARAM;
795         }
796
797         SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
798         /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
799         /*app_label = generate_app_label(pkg_id);
800         if (app_label == NULL) {
801                 C_LOGE("generate_app_label returned NULL.");
802                 return PC_ERR_MEM_OPERATION;
803         }
804
805         ret = rdb_revoke_app_permissions(app_label);
806         if (ret != PC_OPERATION_SUCCESS) {
807                 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
808                 return ret;
809         }*/
810
811         return PC_OPERATION_SUCCESS;
812 }
813
814 API int app_reset_permissions(const char* pkg_id)//deprecated
815 {
816         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
817                                 __func__, pkg_id);
818
819         return perm_app_reset_permissions(pkg_id);
820 }
821
822 API int perm_app_reset_permissions(const char* pkg_id)
823 {
824         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
825                                 __func__, pkg_id);
826         int ret;
827         const char *app_label AUTO_FREE;
828
829         if (!smack_label_is_valid(pkg_id)) {
830                 C_LOGE("Invalid param pkg_id.");
831                 return PC_ERR_INVALID_PARAM;
832         }
833
834         app_label = generate_app_label(pkg_id);
835         if (app_label == NULL) {
836                 C_LOGE("generate_app_label returned NULL.");
837                 return PC_ERR_MEM_OPERATION;
838         }
839
840         ret = rdb_reset_app_permissions(app_label);
841         if (ret != PC_OPERATION_SUCCESS) {
842                 C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
843                 return ret;
844         }
845
846         return PC_OPERATION_SUCCESS;
847 }
848
849 API int app_label_dir(const char* label, const char* path)//deprecated
850 {
851         SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s",
852                                 __func__, label, path);
853
854         int ret = PC_OPERATION_SUCCESS;
855
856         if(path == NULL) {
857                 C_LOGE("Invalid argument path (NULL).");
858                 return PC_ERR_INVALID_PARAM;
859         }
860
861         if (!smack_label_is_valid(label)) {
862                 C_LOGE("Invalid param label.");
863                 return PC_ERR_INVALID_PARAM;
864         }
865
866         //setting access label on everything in given directory and below
867         ret = dir_set_smack_r(path, label, XATTR_NAME_SMACK, &label_all);
868         if (PC_OPERATION_SUCCESS != ret)
869         {
870                 C_LOGE("dir_set_smack_r failed.");
871                 return ret;
872         }
873
874         //setting execute label for everything with permission to execute
875         ret = dir_set_smack_r(path, label, XATTR_NAME_SMACKEXEC, &label_execs);
876         if (PC_OPERATION_SUCCESS != ret)
877         {
878                 C_LOGE("dir_set_smack_r failed.");
879                 return ret;
880         }
881
882         //setting execute label for everything with permission to execute
883         ret = dir_set_smack_r(path, label, XATTR_NAME_TIZENEXEC, &label_links_to_execs);
884         return ret;
885 }
886
887 API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
888 {
889         SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
890                                 __func__, app_label, shared_label, path);
891         int ret;
892
893         if(path == NULL) {
894                 C_LOGE("Invalid param path.");
895                 return PC_ERR_INVALID_PARAM;
896         }
897
898         if(!smack_label_is_valid(app_label)) {
899                 C_LOGE("Invalid param app_label");
900                 return PC_ERR_INVALID_PARAM;
901         }
902
903         if(!smack_label_is_valid(shared_label)) {
904                 C_LOGE("Invalid param shared_label");
905                 return PC_ERR_INVALID_PARAM;
906         }
907
908         if (strcmp(app_label, shared_label) == 0) {
909                 C_LOGE("app_label equals shared_label");
910                 return PC_ERR_INVALID_PARAM;
911         }
912
913         //setting label on everything in given directory and below
914         ret = dir_set_smack_r(path, shared_label, XATTR_NAME_SMACK, label_all);
915         if(ret != PC_OPERATION_SUCCESS){
916                 C_LOGE("dir_set_smack_r failed.");
917                 return ret;
918         }
919
920         //setting transmute on dir
921         ret = dir_set_smack_r(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, label_dirs);
922         if (ret != PC_OPERATION_SUCCESS) {
923                 C_LOGE("dir_set_smack_r failed");
924                 return ret;
925         }
926
927         return PC_OPERATION_SUCCESS;
928 }
929
930 API int add_shared_dir_readers(const char* shared_label UNUSED, const char** app_list UNUSED)//deprecated
931 {
932         SECURE_C_LOGD("Entering function: %s. Params: shared_label=%s",
933                                 __func__, shared_label);
934
935         C_LOGE("add_shared_dir_readers is deprecated and unimplemented!");
936
937         // TODO: This function is not implemented with RDB.
938         return PC_ERR_INVALID_OPERATION;
939 }
940
941 static char* smack_label_for_path(const char *app_id, const char *path)
942 {
943         SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, path=%s",
944                                 __func__, app_id, path);
945
946         char *salt AUTO_FREE;
947         char *label;
948         char *x;
949
950         /* Prefix $1$ causes crypt() to use MD5 function */
951         if (-1 == asprintf(&salt, "$1$%s", app_id)) {
952                 C_LOGE("asprintf failed");
953                 return NULL;
954         }
955
956         label = crypt(path, salt);
957         if (label == NULL) {
958                 C_LOGE("crypt failed");
959                 return NULL;
960         }
961
962         /* crypt() output may contain slash character,
963          * which is not legal in Smack labels */
964         for (x = label; *x; ++x) {
965                 if (*x == '/')
966                         *x = '%';
967         }
968
969         return label;
970 }
971
972 /* FIXME: remove this pragma once deprecated API is deleted */
973 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
974 static int perm_app_setup_path_internal(const char* pkg_id, const char* path, app_path_type_t app_path_type, va_list ap)
975 {
976         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
977                                 __func__, pkg_id, path, app_path_type);
978         const char *app_label AUTO_FREE;
979
980         if(path == NULL) {
981                 C_LOGE("Invalid argument path.");
982                 return PC_ERR_INVALID_PARAM;
983         }
984
985         if (!smack_label_is_valid(pkg_id)) {
986                 C_LOGE("Invalid pkg_id.");
987                 SECURE_C_LOGE("Invalid pkg_id %s", pkg_id);
988                 return PC_ERR_INVALID_PARAM;
989         }
990
991         app_label = generate_app_label(pkg_id);
992         if (app_label == NULL) {
993                 C_LOGE("generate_app_label returned NULL.");
994                 return PC_ERR_MEM_OPERATION;
995         }
996
997         switch (app_path_type) {
998         case APP_PATH_PRIVATE:
999                 C_LOGD("app_path_type is APP_PATH_PRIVATE.");
1000                 return app_label_dir(app_label, path);
1001
1002         case APP_PATH_GROUP_RW: {
1003                 C_LOGD("app_path_type is APP_PATH_GROUP.");
1004                 int ret;
1005                 const char *shared_label;
1006
1007                 shared_label = va_arg(ap, const char *);
1008
1009                 if (!smack_label_is_valid(shared_label)) {
1010                         C_LOGE("Invalid shared_label.");
1011                         return PC_ERR_INVALID_PARAM;
1012                 }
1013
1014                 if (strcmp(app_label, shared_label) == 0) {
1015                         C_LOGE("app_label equals shared_label.");
1016                         return PC_ERR_INVALID_PARAM;
1017                 }
1018
1019                 ret = app_label_shared_dir(app_label, shared_label, path);
1020                 if (ret != PC_OPERATION_SUCCESS) {
1021                         C_LOGE("app_label_shared_dir failed: %d", ret);
1022                         return ret;
1023                 }
1024
1025                 // Add the path to the database:
1026                 ret = rdb_add_path(app_label, shared_label, path, "rwxatl", "-", "GROUP_PATH");
1027                 if (ret != PC_OPERATION_SUCCESS) {
1028                         C_LOGE("RDB rdb_add_path failed with: %d", ret);
1029                         return ret;
1030                 }
1031
1032                 return PC_OPERATION_SUCCESS;
1033         }
1034
1035         case APP_PATH_PUBLIC_RO: {
1036                 C_LOGD("app_path_type is APP_PATH_PUBLIC.");
1037                 const char *label;
1038                 int ret;
1039
1040                 C_LOGD("New public RO path %s", path);
1041
1042                 // Generate label:
1043                 label = smack_label_for_path(app_label, path);
1044                 if (label == NULL) {
1045                         C_LOGE("smack_label_for_path failed.");
1046                         return PC_ERR_INVALID_OPERATION;
1047                 }
1048                 C_LOGD("Generated label '%s' for public RO path %s", label, path);
1049
1050                 ret = app_label_shared_dir(app_label, label, path);
1051                 if (ret != PC_OPERATION_SUCCESS) {
1052                         C_LOGE("app_label_shared_dir failed.");
1053                         return ret;
1054                 }
1055
1056                 // Add the path to the database:
1057                 ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "PUBLIC_PATH");
1058                 if (ret != PC_OPERATION_SUCCESS) {
1059                         C_LOGE("RDB rdb_add_path failed with: %d", ret);
1060                         return ret;
1061                 }
1062
1063                 return PC_OPERATION_SUCCESS;
1064         }
1065
1066         case APP_PATH_SETTINGS_RW: {
1067                 C_LOGD("app_path_type is APP_PATH_SETTINGS.");
1068                 const char *label;
1069                 int ret;
1070
1071                 // Generate label:
1072                 label = smack_label_for_path(app_label, path);
1073                 if (label == NULL) {
1074                         C_LOGE("smack_label_for_path failed.");
1075                         return PC_ERR_INVALID_OPERATION;
1076                 }
1077                 C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
1078
1079                 /*set id for path and all subfolders*/
1080                 ret = app_label_shared_dir(app_label, label, path);
1081                 if (ret != PC_OPERATION_SUCCESS) {
1082                         C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
1083                         return ret;
1084                 }
1085
1086                 // Add the path to the database:
1087                 ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "SETTINGS_PATH");
1088                 if (ret != PC_OPERATION_SUCCESS) {
1089                         C_LOGE("RDB rdb_add_path failed with: %d", ret);
1090                         return ret;
1091                 }
1092
1093                 return PC_OPERATION_SUCCESS;
1094         }
1095
1096         case APP_PATH_ANY_LABEL: {
1097                 C_LOGD("app_path_type is APP_PATH_ANY_LABEL.");
1098                 const char *label = NULL;
1099                 label = va_arg(ap, const char *);
1100                 return app_label_dir(label, path);
1101         }
1102
1103         default:
1104                 C_LOGE("app_path_type is invalid.");
1105                 return PC_ERR_INVALID_PARAM;
1106         }
1107
1108         return PC_OPERATION_SUCCESS;
1109 }
1110 /* FIXME: remove this pragma once deprecated API is deleted */
1111 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
1112
1113 API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)//deprecated
1114 {
1115         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1116                                 __func__, pkg_id, path, app_path_type);
1117
1118         va_list ap;
1119         int ret;
1120         va_start( ap, app_path_type );
1121         ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
1122         va_end( ap );
1123         return ret;
1124 }
1125
1126 API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
1127 {
1128         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1129                                 __func__, pkg_id, path, app_path_type);
1130
1131         va_list ap;
1132         int ret;
1133         va_start( ap, app_path_type );
1134         ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
1135         va_end( ap );
1136         return ret;
1137 }
1138
1139 API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
1140 {
1141         SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
1142                                 __func__, pkg_id1, pkg_id2);
1143
1144         return perm_app_add_friend(pkg_id1, pkg_id2);
1145 }
1146
1147 API int perm_app_add_friend(const char* pkg_id1 UNUSED, const char* pkg_id2 UNUSED)
1148 {
1149         SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
1150                                 __func__, pkg_id1, pkg_id2);
1151
1152         C_LOGE("app_register_av is deprecated and unimplemented!");
1153
1154         // TODO: This function is not implemented with RDB.
1155         return PC_ERR_INVALID_OPERATION;
1156 }
1157
1158 API int app_install(const char* pkg_id)//deprecated
1159 {
1160         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1161                                 __func__, pkg_id);
1162
1163         return perm_app_install(pkg_id);
1164 }
1165
1166 API int perm_app_install(const char* pkg_id)
1167 {
1168         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1169                                 __func__, pkg_id);
1170         int ret;
1171         const char *app_label AUTO_FREE;
1172
1173         if (!smack_label_is_valid(pkg_id)) {
1174                 C_LOGE("Invalid param pkg_id.");
1175                 return PC_ERR_INVALID_PARAM;
1176         }
1177
1178         app_label = generate_app_label(pkg_id);
1179         if (app_label == NULL) {
1180                 C_LOGE("generate_app_label returned NULL.");
1181                 return PC_ERR_MEM_OPERATION;
1182         }
1183
1184         // Add application to the database:
1185         ret = rdb_add_application(app_label);
1186         if (ret != PC_OPERATION_SUCCESS) {
1187                 C_LOGE("RDB rdb_add_application failed with: %d", ret);
1188                 return ret;
1189         }
1190
1191         return PC_OPERATION_SUCCESS;
1192 }
1193
1194 API int app_uninstall(const char* pkg_id)//deprecated
1195 {
1196         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1197                                 __func__, pkg_id);
1198
1199         return perm_app_uninstall(pkg_id);
1200 }
1201
1202 API int perm_app_uninstall(const char* pkg_id)
1203 {
1204         SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1205         /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
1206         /*int ret;
1207         const char *app_label AUTO_FREE;*/
1208
1209         if (!smack_label_is_valid(pkg_id)) {
1210                 C_LOGE("Invalid param pkg_id.");
1211                 return PC_ERR_INVALID_PARAM;
1212         }
1213
1214         SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
1215         /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
1216         /*app_label = generate_app_label(pkg_id);
1217         if (app_label == NULL) {
1218                 C_LOGE("generate_app_label returned NULL.");
1219                 return PC_ERR_MEM_OPERATION;
1220         }
1221
1222         // Remove application from the database
1223         ret = rdb_remove_application(app_label);
1224         if (ret != PC_OPERATION_SUCCESS) {
1225                 C_LOGE("RDB rdb_remove_application failed with: %d", ret);
1226                 return ret;
1227         }*/
1228
1229         return PC_OPERATION_SUCCESS;
1230 }
1231
1232 static int save_gids(FILE* file, const gid_t* list_of_db_gids, size_t list_size) {
1233
1234         SECURE_C_LOGD("Entering function: %s.", __func__);
1235         int ret = PC_OPERATION_SUCCESS;
1236         int written = 0;
1237         size_t i = 0;
1238
1239         if (file == NULL) {
1240                 C_LOGE("Unable to create file. Error: %s", strerror(errno));
1241                 return PC_ERR_FILE_OPERATION;   // TODO remove smack accesses?
1242         }
1243
1244         if(-1 == fchmod(fileno(file), 0644)) {
1245                 C_LOGE("Unable to chmod file. Error: %s", strerror(errno));
1246                 return PC_ERR_FILE_OPERATION;
1247         }
1248
1249         for (i = 0; i < list_size ; ++i) {
1250                 written = fprintf(file, "%u\n", list_of_db_gids[i]);
1251                 if (written <= 0) {
1252                         C_LOGE("fprintf failed for file. Error: %s", strerror(errno));
1253                         ret = PC_ERR_FILE_OPERATION;
1254                         break;
1255                 }
1256         }
1257         return ret;
1258 }
1259
1260 API int add_api_feature(app_type_t app_type,
1261                         const char* api_feature_name,
1262                         const char** smack_rules,
1263                         const gid_t* list_of_db_gids,
1264                         size_t list_size)//deprecated
1265 {
1266         SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
1267                                 __func__, app_type, api_feature_name);
1268
1269     return perm_add_api_feature(app_type, api_feature_name, smack_rules, list_of_db_gids, list_size);
1270 }
1271
1272 API int perm_add_api_feature(app_type_t app_type,
1273                                                 const char* api_feature_name,
1274                                                 const char** smack_rules,
1275                                                 const gid_t* list_of_db_gids,
1276                                                 size_t list_size) {
1277         SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
1278                                 __func__, app_type, api_feature_name);
1279
1280         int ret = PC_OPERATION_SUCCESS;
1281         char* dac_file AUTO_FREE;
1282         char * base_api_feature_name AUTO_FREE;
1283         FILE* file = NULL;
1284         // struct smack_accesses* accesses = NULL;
1285         const char *s_type_name = app_type_name(app_type);
1286
1287         // Check input values
1288         if (s_type_name == NULL || !strcmp(s_type_name, "")) {
1289                 C_LOGE("Unknown api type");
1290                 return PC_ERR_INVALID_PARAM;
1291         }
1292
1293         if (api_feature_name == NULL || strlen(api_feature_name) == 0) {
1294                 C_LOGE("Api feature name is empty.");
1295                 return PC_ERR_INVALID_PARAM;
1296         }
1297
1298         if (smack_rules && ((ret = validate_all_rules(smack_rules) ) != PC_OPERATION_SUCCESS) ) {
1299                 C_LOGE("Error in rules list.");
1300                 return ret;
1301         }
1302
1303         // check .dac existence only if gids are supported
1304         if (list_of_db_gids && list_size > 0) {
1305                 // get feature DAC file name
1306                 ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac", 0);
1307                 if (ret != PC_OPERATION_SUCCESS || !dac_file ) {
1308                         C_LOGE("perm_file_path failed.");
1309                         return ret;
1310                 }
1311
1312                 unlink(dac_file);
1313         }
1314
1315         // go through gid list
1316         if (ret == PC_OPERATION_SUCCESS && list_of_db_gids && list_size > 0) {
1317                 // save to file
1318                 SECURE_C_LOGD("Opening file %s.", dac_file);
1319                 file = fopen(dac_file, "w+");
1320                 ret = save_gids(file, list_of_db_gids, list_size);
1321                 if(file) fclose(file);
1322         }
1323
1324         // remove file in case of failure
1325         if (ret != PC_OPERATION_SUCCESS && dac_file) {
1326                 unlink(dac_file);
1327         }
1328
1329         ret = base_name_from_perm(api_feature_name, &base_api_feature_name);
1330         if (ret != PC_OPERATION_SUCCESS){
1331                 C_LOGE("Error during creating base name: ", ret);
1332                 return ret;
1333         }
1334
1335         // Save api feature to the database.
1336         ret = rdb_add_permission_rules(base_api_feature_name, s_type_name, smack_rules);
1337         if (ret != PC_OPERATION_SUCCESS) {
1338                 C_LOGE("RDB rdb_add_permission_rules failed with: %d", ret);
1339                 return ret;
1340         }
1341
1342         return ret;
1343 }
1344
1345 /**
1346  * This function is marked as deprecated and will be removed
1347  */
1348 API int app_register_av(const char* app_av_id UNUSED)//deprecated
1349 {
1350         SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s",
1351                                 __func__, app_av_id);
1352
1353         C_LOGE("app_register_av is deprecated and unimplemented!");
1354
1355         // TODO: This function is not implemented with RDB.
1356         return PC_ERR_INVALID_OPERATION;
1357 }
1358
1359 API const char* perm_strerror(int errnum)
1360 {
1361         switch (errnum) {
1362         case PC_OPERATION_SUCCESS:
1363                 return "Success";
1364         case PC_ERR_FILE_OPERATION:
1365                 return "File operation error";
1366         case PC_ERR_MEM_OPERATION:
1367                 return "Memory operation error";
1368         case PC_ERR_NOT_PERMITTED:
1369                 return "Operation not permitted";
1370         case PC_ERR_INVALID_PARAM:
1371                 return "Invalid parameter";
1372         case PC_ERR_INVALID_OPERATION:
1373                 return "Invalid operation";
1374         case PC_ERR_DB_OPERATION:
1375                 return "Database operation error";
1376         case PC_ERR_DB_LABEL_TAKEN:
1377                 return "Label taken by another application";
1378         case PC_ERR_DB_QUERY_PREP:
1379                 return "Query failure during preparation";
1380         case PC_ERR_DB_QUERY_BIND:
1381                 return "Query failure during binding";
1382         case PC_ERR_DB_QUERY_STEP:
1383                 return "Query failure during stepping";
1384         case PC_ERR_DB_CONNECTION:
1385                 return "Cannot establish a connection";
1386         case PC_ERR_DB_NO_SUCH_APP:
1387                 return "No such application";
1388         case PC_ERR_DB_PERM_FORBIDDEN:
1389                 return "Duplicate permission";
1390         default:
1391                 return "Unknown error";
1392         }
1393 }
1394
1395 int app_give_access(const char* subject UNUSED, const char* object UNUSED, const char* permission UNUSED) {
1396
1397     return PC_ERR_INVALID_OPERATION;
1398 }
1399
1400 int app_revoke_access(const char* subject UNUSED, const char* object UNUSED) {
1401     return PC_ERR_INVALID_OPERATION;
1402 }