• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pms.h"
17 
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 
22 #include "cJSON.h"
23 #include "log.h"
24 #include "securec.h"
25 
26 #include "hal_pms.h"
27 #include "perm_operate.h"
28 
29 #define BUFF_PARAM_SIZE 16
30 #define BUFF_SIZE_MAX_LENGTH 1024
31 #define FIELD_PERMISSION "permissions"
32 #define FIELD_NAME "name"
33 #define FIELD_DESC "desc"
34 #define FIELD_IS_GRANTED "isGranted"
35 #define FIELD_FLAGS "flags"
36 
37 // Permission matrix of run-time tasks
38 static struct TaskList g_taskList = {
39     NULL
40 };
41 
42 // don't forget free() afterwards
ConcatString(const char * s1,const char * s2)43 static char *ConcatString(const char *s1, const char *s2)
44 {
45     unsigned int allocSize = strlen(s1) + strlen(s2) + 1;
46     if (allocSize > BUFF_SIZE_MAX_LENGTH) {
47         return NULL;
48     }
49     char *rst = (char *)HalMalloc(allocSize);
50     if (rst == NULL) {
51         return NULL;
52     }
53     if (memset_s(rst, allocSize, 0x0, allocSize) != EOK) {
54         HalFree(rst);
55         return NULL;
56     }
57     if (strcpy_s(rst, allocSize, s1) != EOK) {
58         HalFree(rst);
59         return NULL;
60     }
61     if (strcat_s(rst, allocSize, s2) != EOK) {
62         HalFree(rst);
63         return NULL;
64     }
65     return rst;
66 }
67 
WriteString(const char * path,const char * string)68 static int WriteString(const char *path, const char *string)
69 {
70     int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
71     if (fd < 0) {
72         return PERM_ERRORCODE_OPENFD_FAIL;
73     }
74     int stringLength = strlen(string);
75     int writtenLength = write(fd, (void*)string, stringLength);
76     close(fd);
77     if (writtenLength != stringLength) {
78         unlink(path);
79         return PERM_ERRORCODE_WRITEFD_FAIL;
80     }
81     return PERM_ERRORCODE_SUCCESS;
82 }
83 
84 // don't forget to call free() afterwards
ReadString(const char * path,int * errCode)85 static char *ReadString(const char *path, int *errCode)
86 {
87     if (!HalIsValidPath(path)) {
88         *errCode = PERM_ERRORCODE_PATH_INVALID;
89         return NULL;
90     }
91     struct stat buf = { 0 };
92     if (stat(path, &buf) || ((buf.st_mode & S_IFREG) != S_IFREG)) {
93         *errCode = PERM_ERRORCODE_STAT_FAIL;
94         return NULL;
95     }
96     unsigned int readSize = buf.st_size;
97     char *rst = (char *)HalMalloc(readSize);
98     if (rst == NULL) {
99         *errCode = PERM_ERRORCODE_MALLOC_FAIL;
100         return NULL;
101     }
102 
103     if (memset_s(rst, readSize, 0x0, readSize) != EOK) {
104         HalFree(rst);
105         *errCode = PERM_ERRORCODE_MEMSET_FAIL;
106         return NULL;
107     }
108 
109     int fd = open(path, O_RDONLY, S_IRUSR | S_IWUSR);
110     if (fd < 0) {
111         HalFree(rst);
112         *errCode = PERM_ERRORCODE_OPENFD_FAIL;
113         return NULL;
114     }
115 
116     int ret = read(fd, rst, readSize);
117     close(fd);
118     if (ret < 0) {
119         HalFree(rst);
120         *errCode = PERM_ERRORCODE_READFD_FAIL;
121         return NULL;
122     }
123     return rst;
124 }
125 
GetPath(const char * identifier)126 static char *GetPath(const char *identifier)
127 {
128     return ConcatString(HalGetPermissionPath(), identifier);
129 }
130 
GetPermissionType(const char * permission)131 static int GetPermissionType(const char *permission)
132 {
133     unsigned int permSize = 0;
134     PermissionDef *permList = HalGetPermissionList(&permSize);
135 
136     for (int i = 0; i < permSize; i++) {
137         if (strcmp(permission, permList[i].name) == 0) {
138             return permList[i].type;
139         }
140     }
141     return PERM_ERRORCODE_INVALID_PERMNAME;
142 }
143 
ParseFixedPermissionsItem(const cJSON * object,PermissionSaved * perms)144 static int ParseFixedPermissionsItem(const cJSON *object, PermissionSaved *perms)
145 {
146     cJSON *itemName = cJSON_GetObjectItem(object, FIELD_NAME);
147     cJSON *itemDesc = cJSON_GetObjectItem(object, FIELD_DESC);
148     cJSON *itemGranted = cJSON_GetObjectItem(object, FIELD_IS_GRANTED);
149     if (itemName == NULL || itemDesc == NULL || itemGranted == NULL ||
150         !cJSON_IsString(itemName) || !cJSON_IsString(itemDesc) || itemName->valuestring == NULL) {
151         return PERM_ERRORCODE_JSONPARSE_FAIL;
152     }
153     if (strcpy_s(perms->name, PERM_NAME_LEN, itemName->valuestring) != EOK) {
154         return PERM_ERRORCODE_COPY_ERROR;
155     }
156     if (strcpy_s(perms->desc, PERM_DESC_LEN, itemDesc->valuestring) != EOK) {
157         return PERM_ERRORCODE_COPY_ERROR;
158     }
159     perms->granted = (enum IsGranted)itemGranted->valueint;
160     return PERM_ERRORCODE_SUCCESS;
161 }
162 
ParseNewPermissionsItem(const cJSON * object,PermissionSaved * perms)163 static int ParseNewPermissionsItem(const cJSON *object, PermissionSaved *perms)
164 {
165     cJSON *itemFlags = cJSON_GetObjectItem(object, FIELD_FLAGS);
166     if (itemFlags == NULL || !cJSON_IsString(itemFlags) || itemFlags->valuestring == NULL) {
167         perms->flags = PMS_FLAG_DEFAULT;
168         return PERM_ERRORCODE_JSONPARSE_FAIL;
169     }
170     perms->flags = atoi(itemFlags->valuestring);
171     return PERM_ERRORCODE_SUCCESS;
172 }
173 
174 
ParsePermissions(const char * jsonStr,PermissionSaved ** perms,int * permNum)175 static int ParsePermissions(const char *jsonStr, PermissionSaved **perms, int *permNum)
176 {
177     cJSON *root = cJSON_Parse(jsonStr);
178     if (root == NULL) {
179         return PERM_ERRORCODE_JSONPARSE_FAIL;
180     }
181     int ret;
182     cJSON *array = cJSON_GetObjectItem(root, FIELD_PERMISSION);
183     int pSize = cJSON_GetArraySize(array);
184     int allocSize = sizeof(PermissionSaved) * pSize;
185     if (allocSize == 0) {
186         cJSON_Delete(root);
187         return PERM_ERRORCODE_SUCCESS;
188     }
189     *perms = (PermissionSaved *)HalMalloc(allocSize);
190     if (*perms == NULL) {
191         cJSON_Delete(root);
192         return PERM_ERRORCODE_MALLOC_FAIL;
193     }
194     for (int i = 0; i < pSize; i++) {
195         cJSON *object = cJSON_GetArrayItem(array, i);
196         ret = ParseFixedPermissionsItem(object, *perms + i);
197         if (ret != PERM_ERRORCODE_SUCCESS) {
198             cJSON_Delete(root);
199             HalFree(*perms);
200             *perms = NULL;
201             return ret;
202         }
203         ret = ParseNewPermissionsItem(object, *perms + i);
204         if (ret != PERM_ERRORCODE_SUCCESS) {
205             cJSON_Delete(root);
206             HalFree(*perms);
207             *perms = NULL;
208             return ret;
209         }
210     }
211     *permNum = pSize;
212     cJSON_Delete(root);
213     return PERM_ERRORCODE_SUCCESS;
214 }
215 
WritePermissions(const char * identifier,const cJSON * root)216 static int WritePermissions(const char *identifier, const cJSON *root)
217 {
218     const char *path = GetPath(identifier);
219     if (path == NULL) {
220         return PERM_ERRORCODE_PATH_INVALID;
221     }
222     const char *jsonStr = cJSON_PrintUnformatted(root);
223     if (jsonStr == NULL) {
224         HalFree(path);
225         return PERM_ERRORCODE_MALLOC_FAIL;
226     }
227     int ret = WriteString(path, jsonStr);
228     HalFree(path);
229     cJSON_free(jsonStr);
230     return ret;
231 }
232 
SavePermissions(const char * identifier,const PermissionSaved * permissions,int permNum)233 static int SavePermissions(const char *identifier, const PermissionSaved *permissions, int permNum)
234 {
235     if (identifier == NULL || permissions == NULL) {
236         return PERM_ERRORCODE_INVALID_PARAMS;
237     }
238 
239     char buf[BUFF_PARAM_SIZE] = {0};
240     cJSON *root = cJSON_CreateObject();
241     if (root == NULL) {
242         return PERM_ERRORCODE_MALLOC_FAIL;
243     }
244     cJSON *array = cJSON_CreateArray();
245     if (array == NULL) {
246         cJSON_Delete(root);
247         return PERM_ERRORCODE_MALLOC_FAIL;
248     }
249     for (int i = 0; i < permNum; i++) {
250         cJSON *object = cJSON_CreateObject();
251         if (object == NULL) {
252             cJSON_Delete(array);
253             cJSON_Delete(root);
254             return PERM_ERRORCODE_MALLOC_FAIL;
255         }
256         cJSON_AddItemToObject(object, FIELD_NAME, cJSON_CreateString(permissions[i].name));
257         cJSON_AddItemToObject(object, FIELD_DESC, cJSON_CreateString(permissions[i].desc));
258         cJSON_AddItemToObject(object, FIELD_IS_GRANTED, cJSON_CreateBool(permissions[i].granted));
259 
260         if (memset_s(buf, BUFF_PARAM_SIZE, 0, BUFF_PARAM_SIZE) != EOK) {
261             cJSON_Delete(array);
262             cJSON_Delete(root);
263             cJSON_Delete(object);
264             return PERM_ERRORCODE_MEMSET_FAIL;
265         }
266         if (sprintf_s(buf, BUFF_PARAM_SIZE, "%d", permissions[i].flags) < 0) {
267             cJSON_Delete(array);
268             cJSON_Delete(root);
269             cJSON_Delete(object);
270             return PERM_ERRORCODE_SPRINTFS_FAIL;
271         }
272         cJSON_AddItemToObject(object, FIELD_FLAGS, cJSON_CreateString(buf));
273         cJSON_AddItemToArray(array, object);
274     }
275     cJSON_AddItemToObject(root, FIELD_PERMISSION, array);
276     int ret = WritePermissions(identifier, root);
277     cJSON_Delete(root);
278     return ret;
279 }
280 
IsValidFlags(const unsigned int flags)281 static bool IsValidFlags(const unsigned int flags)
282 {
283     if ((flags == PMS_FLAG_DEFAULT) || ((flags & (~PMS_FLAG_VALID_MASK)) == PMS_FLAG_DEFAULT)) {
284         return true;
285     }
286     return false;
287 }
288 
QueryPermissionString(const char * identifier,int * errCode)289 char *QueryPermissionString(const char *identifier, int *errCode)
290 {
291     if (identifier == NULL) {
292         *errCode = PERM_ERRORCODE_INVALID_PARAMS;
293         return NULL;
294     }
295 
296     int ret;
297     char *path = NULL;
298     char *jsonStr = NULL;
299 
300     path = GetPath(identifier);
301     if (path == NULL) {
302         *errCode = PERM_ERRORCODE_MALLOC_FAIL;
303         return NULL;
304     }
305     ret = HalAccess(path);
306     if (ret) {
307         HalFree(path);
308         *errCode = PERM_ERRORCODE_FILE_NOT_EXIST;
309         return NULL;
310     }
311 
312     jsonStr = ReadString(path, errCode);
313     HalFree(path);
314     return jsonStr;
315 }
316 
QueryPermission(const char * identifier,PermissionSaved ** permissions,int * permNum)317 int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)
318 {
319     int errCode = 0;
320     const char *jsonStr = QueryPermissionString(identifier, &errCode);
321     if (errCode) {
322         return errCode;
323     }
324 
325     int ret = ParsePermissions(jsonStr, permissions, permNum);
326     HalFree(jsonStr);
327     return ret;
328 }
329 
QueryAppCapabilities(const char * identifier,unsigned int ** caps,unsigned int * capNum)330 int QueryAppCapabilities(const char *identifier, unsigned int **caps, unsigned int *capNum)
331 {
332     if (caps == NULL || capNum == NULL) {
333         return PERM_ERRORCODE_INVALID_PARAMS;
334     }
335     PermissionSaved *permissions = NULL;
336     int permNum = 0;
337     int ret = QueryPermission(identifier, &permissions, &permNum);
338     if (ret != PERM_ERRORCODE_SUCCESS) {
339         return ret;
340     }
341     unsigned int allocSize = sizeof(unsigned int) * permNum;
342     if (allocSize == 0) {
343         HalFree(permissions);
344         return PERM_ERRORCODE_SUCCESS;
345     }
346     unsigned int *capsBinded = (unsigned int *)HalMalloc(allocSize);
347     if (capsBinded == NULL) {
348         HalFree(permissions);
349         return PERM_ERRORCODE_MALLOC_FAIL;
350     }
351 
352     unsigned int permSize = 0;
353     PermissionDef *permList = HalGetPermissionList(&permSize);
354     unsigned int index = 0;
355     for (int j = 0; j < permNum; j++) {
356         for (int i = 0; i < permSize; i++) {
357             if (strcmp(permissions[j].name, permList[i].name) || permList[i].cap == CAP_NOT_BINDED) {
358                 continue;
359             }
360             capsBinded[index] = permList[i].cap;
361             index++;
362             break;
363         }
364     }
365     HalFree(permissions);
366     allocSize = sizeof(unsigned int) * index;
367     if (allocSize == 0) {
368         HalFree(capsBinded);
369         return PERM_ERRORCODE_SUCCESS;
370     }
371     *caps = (unsigned int *)HalMalloc(allocSize);
372     if (*caps == NULL) {
373         HalFree(capsBinded);
374         return PERM_ERRORCODE_MALLOC_FAIL;
375     }
376     for (int k = 0; k < index; k++) {
377         *(*caps + k) = capsBinded[k];
378     }
379     *capNum = index;
380     HalFree(capsBinded);
381     return PERM_ERRORCODE_SUCCESS;
382 }
383 
UpdateAppPermission(const char * identifier,const PermissionTrans newPerms[],int newPermNum,enum IsUpdate isUpdate)384 static int UpdateAppPermission(
385     const char *identifier, const PermissionTrans newPerms[], int newPermNum, enum IsUpdate isUpdate)
386 {
387     PermissionSaved *permissions = NULL;
388     int permNum = 0;
389     int retCode = PERM_ERRORCODE_SUCCESS;
390     if (isUpdate == UPDATE) {
391         retCode = QueryPermission(identifier, &permissions, &permNum);
392     }
393     if ((retCode != PERM_ERRORCODE_SUCCESS) && (retCode != PERM_ERRORCODE_FILE_NOT_EXIST)) {
394         return retCode;
395     }
396     int allocSize = sizeof(PermissionSaved) * newPermNum;
397     PermissionSaved *updatePerms = (PermissionSaved *)HalMalloc(allocSize);
398     if (updatePerms == NULL) {
399         HalFree(permissions);
400         return PERM_ERRORCODE_MALLOC_FAIL;
401     }
402     for (int i = 0; i < newPermNum; i++) {
403         if (strlen(newPerms[i].name) > PERM_NAME_LEN - 1 || strlen(newPerms[i].desc) > PERM_DESC_LEN - 1) {
404             HalFree(updatePerms);
405             HalFree(permissions);
406             return PERM_ERRORCODE_FIELD_TOO_LONG;
407         }
408         if (strcpy_s(updatePerms[i].name, PERM_NAME_LEN, newPerms[i].name) != EOK) {
409             HalFree(updatePerms);
410             HalFree(permissions);
411             return PERM_ERRORCODE_COPY_ERROR;
412         }
413         if (strcpy_s(updatePerms[i].desc, PERM_DESC_LEN, newPerms[i].desc) != EOK) {
414             HalFree(updatePerms);
415             HalFree(permissions);
416             return PERM_ERRORCODE_COPY_ERROR;
417         }
418         int permType = GetPermissionType(newPerms[i].name);
419         updatePerms[i].granted = NOT_GRANTED;
420         updatePerms[i].flags = PMS_FLAG_DEFAULT;
421         if (permType != PERM_ERRORCODE_INVALID_PERMNAME) {
422             updatePerms[i].granted = (permType == SYSTEM_GRANT) ? GRANTED : NOT_GRANTED;
423         }
424         for (int j = 0; j < permNum; j++) {
425             if (strcmp(newPerms[i].name, (permissions + j)->name) == 0) {
426                 updatePerms[i].granted = permissions[j].granted;
427             }
428         }
429     }
430     retCode = SavePermissions(identifier, updatePerms, newPermNum);
431     HalFree(updatePerms);
432     HalFree(permissions);
433     return retCode;
434 }
435 
SaveOrUpdatePermissions(const char * identifier,PermissionTrans permissions[],int permNum,enum IsUpdate isUpdate)436 int SaveOrUpdatePermissions(
437     const char *identifier, PermissionTrans permissions[], int permNum, enum IsUpdate isUpdate)
438 {
439     if ((identifier == NULL) || (permissions == NULL) || (permNum < 0) ||
440         (isUpdate != UPDATE && isUpdate != FIRST_INSTALL)) {
441         return PERM_ERRORCODE_INVALID_PARAMS;
442     }
443     if (permNum > HalGetMaxPermissionSize()) {
444         return PERM_ERRORCODE_TOO_MUCH_PERM;
445     }
446     char *path = GetPath(identifier);
447     if (path == NULL) {
448         return PERM_ERRORCODE_MALLOC_FAIL;
449     }
450     if (permNum == 0) {
451         unlink(path);
452         HalFree(path);
453         return PERM_ERRORCODE_SUCCESS;
454     }
455     HalFree(path);
456 
457     int distinctNum = 0;
458     int *flag = (int *)HalMalloc(permNum * sizeof(int));
459     if (flag == NULL) {
460         return PERM_ERRORCODE_MALLOC_FAIL;
461     }
462     (void)memset_s(flag, permNum * sizeof(int), 0, permNum * sizeof(int));
463     for (int i = 0; i < permNum; i++) {
464         if (flag[i] != 0) {
465             continue;
466         }
467         permissions[distinctNum++] = permissions[i];
468         for (int j = i + 1; j < permNum; j++) {
469             if (strcmp(permissions[i].name, permissions[j].name) == 0) {
470                 flag[j] = 1;
471             }
472         }
473     }
474     HalFree(flag);
475 
476     return UpdateAppPermission(identifier, permissions, distinctNum, isUpdate);
477 }
478 
DeletePermissions(const char * identifier)479 int DeletePermissions(const char *identifier)
480 {
481     if (identifier == NULL) {
482         return PERM_ERRORCODE_INVALID_PARAMS;
483     }
484     int ret;
485     char *path = NULL;
486     path = GetPath(identifier);
487     if (path == NULL) {
488         return PERM_ERRORCODE_MALLOC_FAIL;
489     }
490 
491     ret = HalAccess(path);
492     if (ret != 0) {
493         HalFree(path);
494         return PERM_ERRORCODE_SUCCESS;
495     }
496 
497     ret = unlink(path);
498     HalFree(path);
499     return (ret != 0) ? PERM_ERRORCODE_UNLINK_ERROR : PERM_ERRORCODE_SUCCESS;
500 }
501 
IsPermissionValid(const char * permissionName)502 int IsPermissionValid(const char *permissionName)
503 {
504     unsigned int permSize = 0;
505     PermissionDef *permList = HalGetPermissionList(&permSize);
506 
507     for (int i = 0; i < permSize; i++) {
508         if (strcmp(permissionName, permList[i].name) == 0) {
509             return PERM_ERRORCODE_SUCCESS;
510         }
511     }
512     return PERM_ERRORCODE_INVALID_PERMNAME;
513 }
514 
IsPermissionRestricted(const char * permissionName)515 int IsPermissionRestricted(const char *permissionName)
516 {
517     unsigned int permSize = 0;
518     PermissionDef *permList = HalGetPermissionList(&permSize);
519 
520     for (int i = 0; i < permSize; i++) {
521         if (strcmp(permissionName, permList[i].name) == 0) {
522             return permList[i].isRestricted;
523         }
524     }
525     return PERM_ERRORCODE_INVALID_PERMNAME;
526 }
527 
LoadPermissions(const char * identifier,int uid)528 int LoadPermissions(const char *identifier, int uid)
529 {
530     if (uid < 0 || identifier == NULL) {
531         return PERM_ERRORCODE_INVALID_PARAMS;
532     }
533 
534     HalMutexLock();
535     TNode *task = GetTaskWithUid(&g_taskList, uid);
536     if (task != NULL) {
537         HalMutexUnlock();
538         return PERM_ERRORCODE_SUCCESS;
539     }
540 
541     PermissionSaved *permissions = NULL;
542     int permNum = 0;
543     int ret = QueryPermission(identifier, &permissions, &permNum);
544     if (ret == PERM_ERRORCODE_FILE_NOT_EXIST) {
545         HILOG_ERROR(HILOG_MODULE_APP, "Perm file not exists.");
546         HalMutexUnlock();
547         return PERM_ERRORCODE_SUCCESS;
548     }
549     if (ret != PERM_ERRORCODE_SUCCESS) {
550         HalMutexUnlock();
551         return ret;
552     }
553     TNode *node = (TNode *)HalMalloc(sizeof(TNode));
554     if (node == NULL) {
555         HalFree(permissions);
556         HalMutexUnlock();
557         return PERM_ERRORCODE_MALLOC_FAIL;
558     }
559     node->uid = uid;
560     if (strcpy_s(node->pkgName, PKG_NAME_LEN, identifier) != EOK) {
561         HalFree(permissions);
562         HalFree(node);
563         HalMutexUnlock();
564         return PERM_ERRORCODE_COPY_ERROR;
565     }
566     node->permList = permissions;
567     node->permNum = permNum;
568     node->next = NULL;
569 
570     AddTask(&g_taskList, node);
571     HalMutexUnlock();
572 
573     return PERM_ERRORCODE_SUCCESS;
574 }
575 
UnLoadPermissions(int uid)576 int UnLoadPermissions(int uid)
577 {
578     HalMutexLock();
579     DeleteTask(&g_taskList, uid);
580     HalMutexUnlock();
581     return PERM_ERRORCODE_SUCCESS;
582 }
583 
CheckPermissionStat(int uid,const char * permissionName)584 int CheckPermissionStat(int uid, const char *permissionName)
585 {
586     if (uid < 0 || permissionName == NULL) {
587         return PERM_ERRORCODE_INVALID_PARAMS;
588     }
589     HalMutexLock();
590     int ret = PermissionIsGranted(&g_taskList, uid, permissionName);
591     HalMutexUnlock();
592     return ret;
593 }
594 
OnPermissionFileSync(const char * identifier,const char * permName,const enum IsGranted granted)595 static int OnPermissionFileSync(const char *identifier, const char *permName, const enum IsGranted granted)
596 {
597     int retCode = PERM_ERRORCODE_SUCCESS;
598     bool isSave = false;
599     PermissionSaved *permissions = NULL;
600     int permNum = 0;
601     int ret = QueryPermission(identifier, &permissions, &permNum);
602     if (ret != PERM_ERRORCODE_SUCCESS) {
603         return ret;
604     }
605     for (int i = 0; i < permNum; i++) {
606         if (strcmp(permissions[i].name, permName) == 0) {
607             isSave = permissions[i].granted ^ granted;
608             permissions[i].granted = granted;
609             break;
610         }
611     }
612     if (isSave) {
613         retCode = SavePermissions(identifier, permissions, permNum);
614     }
615     HalFree(permissions);
616     return retCode;
617 }
618 
OnPermissionFlagsFileSync(const char * identifier,const char * permName,const int flags)619 static int OnPermissionFlagsFileSync(const char *identifier, const char *permName, const int flags)
620 {
621     int retCode = PERM_ERRORCODE_SUCCESS;
622     bool isSave = false;
623     PermissionSaved *permissions = NULL;
624     int permNum = 0;
625     int ret = QueryPermission(identifier, &permissions, &permNum);
626     if (ret != PERM_ERRORCODE_SUCCESS) {
627         return ret;
628     }
629     for (int i = 0; i < permNum; i++) {
630         if (strcmp(permissions[i].name, permName) == 0) {
631             isSave = permissions[i].flags ^ flags;
632             permissions[i].flags = flags;
633             break;
634         }
635     }
636     if (isSave) {
637         retCode = SavePermissions(identifier, permissions, permNum);
638     }
639     HalFree(permissions);
640     return retCode;
641 }
642 
GrantPermission(const char * identifier,const char * permName)643 int GrantPermission(const char *identifier, const char *permName)
644 {
645     if ((identifier == NULL) || (permName == NULL)) {
646         return PERM_ERRORCODE_INVALID_PARAMS;
647     }
648     int ret = PERM_ERRORCODE_SUCCESS;
649     HalMutexLock();
650     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
651     if (node != NULL) {
652         ret = ModifyPermission(node, permName, GRANTED);
653     }
654     HalMutexUnlock();
655 
656     if (ret != 0) {
657         return PERM_ERRORCODE_PERM_NOT_EXIST;
658     }
659 
660     return OnPermissionFileSync(identifier, permName, GRANTED);
661 }
662 
RevokePermission(const char * identifier,const char * permName)663 int RevokePermission(const char *identifier, const char *permName)
664 {
665     if ((identifier == NULL) || (permName == NULL)) {
666         return PERM_ERRORCODE_INVALID_PARAMS;
667     }
668     int ret = PERM_ERRORCODE_SUCCESS;
669     HalMutexLock();
670     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
671     if (node != NULL) {
672         ret = ModifyPermission(node, permName, NOT_GRANTED);
673     }
674     HalMutexUnlock();
675 
676     if (ret != 0) {
677         return PERM_ERRORCODE_PERM_NOT_EXIST;
678     }
679 
680     return OnPermissionFileSync(identifier, permName, NOT_GRANTED);
681 }
682 
GrantRuntimePermission(int uid,const char * permissionName)683 int GrantRuntimePermission(int uid, const char *permissionName)
684 {
685     if (permissionName == NULL) {
686         return PERM_ERRORCODE_INVALID_PARAMS;
687     }
688 
689     HalMutexLock();
690     TNode *node = GetTaskWithUid(&g_taskList, uid);
691     if (node == NULL) {
692         HalMutexUnlock();
693         return PERM_ERRORCODE_TASKID_NOT_EXIST;
694     }
695 
696     int ret = ModifyPermission(node, permissionName, GRANTED);
697     HalMutexUnlock();
698     if (ret < 0) {
699         return PERM_ERRORCODE_PERM_NOT_EXIST;
700     }
701 
702     return OnPermissionFileSync(node->pkgName, permissionName, GRANTED);
703 }
704 
RevokeRuntimePermission(int uid,const char * permissionName)705 int RevokeRuntimePermission(int uid, const char *permissionName)
706 {
707     if (permissionName == NULL) {
708         return PERM_ERRORCODE_INVALID_PARAMS;
709     }
710 
711     HalMutexLock();
712     TNode *node = GetTaskWithUid(&g_taskList, uid);
713     if (node == NULL) {
714         HalMutexUnlock();
715         return PERM_ERRORCODE_TASKID_NOT_EXIST;
716     }
717 
718     int ret = ModifyPermission(node, permissionName, NOT_GRANTED);
719     HalMutexUnlock();
720     if (ret < 0) {
721         return PERM_ERRORCODE_PERM_NOT_EXIST;
722     }
723 
724     return OnPermissionFileSync(node->pkgName, permissionName, NOT_GRANTED);
725 }
726 
UpdatePermissionFlags(const char * identifier,const char * permissionName,const int flags)727 int UpdatePermissionFlags(const char *identifier, const char *permissionName, const int flags)
728 {
729     if ((identifier == NULL) || (permissionName == NULL) || !IsValidFlags(flags)) {
730         return PERM_ERRORCODE_INVALID_PARAMS;
731     }
732 
733     return OnPermissionFlagsFileSync(identifier, permissionName, flags);
734 }
735