• 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((void *)rst);
55         return NULL;
56     }
57     if (strcpy_s(rst, allocSize, s1) != EOK) {
58         HalFree((void *)rst);
59         return NULL;
60     }
61     if (strcat_s(rst, allocSize, s2) != EOK) {
62         HalFree((void *)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((void *)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((void *)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((void *)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     cJSON *array = cJSON_GetObjectItem(root, FIELD_PERMISSION);
182     int pSize = cJSON_GetArraySize(array);
183     int allocSize = sizeof(PermissionSaved) * pSize;
184     if (allocSize == 0) {
185         cJSON_Delete(root);
186         return PERM_ERRORCODE_SUCCESS;
187     }
188     *perms = (PermissionSaved *)HalMalloc(allocSize);
189     if (*perms == NULL) {
190         cJSON_Delete(root);
191         return PERM_ERRORCODE_MALLOC_FAIL;
192     }
193     for (int i = 0; i < pSize; i++) {
194         cJSON *object = cJSON_GetArrayItem(array, i);
195         int ret = ParseFixedPermissionsItem(object, *perms + i);
196         if (ret != PERM_ERRORCODE_SUCCESS) {
197             cJSON_Delete(root);
198             HalFree((void *)*perms);
199             *perms = NULL;
200             return ret;
201         }
202         ret = ParseNewPermissionsItem(object, *perms + i);
203         if (ret != PERM_ERRORCODE_SUCCESS) {
204             cJSON_Delete(root);
205             HalFree((void *)*perms);
206             *perms = NULL;
207             return ret;
208         }
209     }
210     *permNum = pSize;
211     cJSON_Delete(root);
212     return PERM_ERRORCODE_SUCCESS;
213 }
214 
WritePermissions(const char * identifier,const cJSON * root)215 static int WritePermissions(const char *identifier, const cJSON *root)
216 {
217     const char *path = GetPath(identifier);
218     if (path == NULL) {
219         return PERM_ERRORCODE_PATH_INVALID;
220     }
221     const char *jsonStr = cJSON_PrintUnformatted(root);
222     if (jsonStr == NULL) {
223         HalFree((void *)path);
224         return PERM_ERRORCODE_MALLOC_FAIL;
225     }
226     int ret = WriteString(path, jsonStr);
227     HalFree((void *)path);
228     cJSON_free((void *)jsonStr);
229     return ret;
230 }
231 
SavePermissions(const char * identifier,const PermissionSaved * permissions,int permNum)232 static int SavePermissions(const char *identifier, const PermissionSaved *permissions, int permNum)
233 {
234     if (identifier == NULL || permissions == NULL) {
235         return PERM_ERRORCODE_INVALID_PARAMS;
236     }
237 
238     char buf[BUFF_PARAM_SIZE] = {0};
239     cJSON *root = cJSON_CreateObject();
240     if (root == NULL) {
241         return PERM_ERRORCODE_MALLOC_FAIL;
242     }
243     cJSON *array = cJSON_CreateArray();
244     if (array == NULL) {
245         cJSON_Delete(root);
246         return PERM_ERRORCODE_MALLOC_FAIL;
247     }
248     for (int i = 0; i < permNum; i++) {
249         cJSON *object = cJSON_CreateObject();
250         if (object == NULL) {
251             cJSON_Delete(array);
252             cJSON_Delete(root);
253             return PERM_ERRORCODE_MALLOC_FAIL;
254         }
255         cJSON_AddItemToObject(object, FIELD_NAME, cJSON_CreateString(permissions[i].name));
256         cJSON_AddItemToObject(object, FIELD_DESC, cJSON_CreateString(permissions[i].desc));
257         cJSON_AddItemToObject(object, FIELD_IS_GRANTED, cJSON_CreateBool(permissions[i].granted));
258 
259         if (memset_s(buf, BUFF_PARAM_SIZE, 0, BUFF_PARAM_SIZE) != EOK) {
260             cJSON_Delete(array);
261             cJSON_Delete(root);
262             cJSON_Delete(object);
263             return PERM_ERRORCODE_MEMSET_FAIL;
264         }
265         if (sprintf_s(buf, BUFF_PARAM_SIZE, "%d", permissions[i].flags) < 0) {
266             cJSON_Delete(array);
267             cJSON_Delete(root);
268             cJSON_Delete(object);
269             return PERM_ERRORCODE_SPRINTFS_FAIL;
270         }
271         cJSON_AddItemToObject(object, FIELD_FLAGS, cJSON_CreateString(buf));
272         cJSON_AddItemToArray(array, object);
273     }
274     cJSON_AddItemToObject(root, FIELD_PERMISSION, array);
275     int ret = WritePermissions(identifier, root);
276     cJSON_Delete(root);
277     return ret;
278 }
279 
IsValidFlags(const unsigned int flags)280 static bool IsValidFlags(const unsigned int flags)
281 {
282     if ((flags == PMS_FLAG_DEFAULT) || ((flags & (~PMS_FLAG_VALID_MASK)) == PMS_FLAG_DEFAULT)) {
283         return true;
284     }
285     return false;
286 }
287 
QueryPermissionString(const char * identifier,int * errCode)288 char *QueryPermissionString(const char *identifier, int *errCode)
289 {
290     if (identifier == NULL) {
291         *errCode = PERM_ERRORCODE_INVALID_PARAMS;
292         return NULL;
293     }
294 
295     int ret;
296     char *path = NULL;
297     char *jsonStr = NULL;
298 
299     path = GetPath(identifier);
300     if (path == NULL) {
301         *errCode = PERM_ERRORCODE_MALLOC_FAIL;
302         return NULL;
303     }
304     ret = HalAccess(path);
305     if (ret) {
306         HalFree((void *)path);
307         *errCode = PERM_ERRORCODE_FILE_NOT_EXIST;
308         return NULL;
309     }
310 
311     jsonStr = ReadString(path, errCode);
312     HalFree((void *)path);
313     return jsonStr;
314 }
315 
QueryPermission(const char * identifier,PermissionSaved ** permissions,int * permNum)316 int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)
317 {
318     int errCode = 0;
319     const char *jsonStr = QueryPermissionString(identifier, &errCode);
320     if (errCode) {
321         return errCode;
322     }
323 
324     int ret = ParsePermissions(jsonStr, permissions, permNum);
325     HalFree((void *)jsonStr);
326     return ret;
327 }
328 
QueryAppCapabilities(const char * identifier,unsigned int ** caps,unsigned int * capNum)329 int QueryAppCapabilities(const char *identifier, unsigned int **caps, unsigned int *capNum)
330 {
331     if (caps == NULL || capNum == NULL) {
332         return PERM_ERRORCODE_INVALID_PARAMS;
333     }
334     PermissionSaved *permissions = NULL;
335     int permNum = 0;
336     int ret = QueryPermission(identifier, &permissions, &permNum);
337     if (ret != PERM_ERRORCODE_SUCCESS) {
338         return ret;
339     }
340     unsigned int allocSize = sizeof(unsigned int) * permNum;
341     if (allocSize == 0) {
342         HalFree((void *)permissions);
343         return PERM_ERRORCODE_SUCCESS;
344     }
345     unsigned int *capsBinded = (unsigned int *)HalMalloc(allocSize);
346     if (capsBinded == NULL) {
347         HalFree((void *)permissions);
348         return PERM_ERRORCODE_MALLOC_FAIL;
349     }
350 
351     unsigned int permSize = 0;
352     PermissionDef *permList = HalGetPermissionList(&permSize);
353     unsigned int index = 0;
354     for (int j = 0; j < permNum; j++) {
355         for (int i = 0; i < permSize; i++) {
356             if (strcmp(permissions[j].name, permList[i].name) || permList[i].cap == CAP_NOT_BINDED) {
357                 continue;
358             }
359             capsBinded[index++] = permList[i].cap;
360             break;
361         }
362     }
363     HalFree((void *)permissions);
364     allocSize = sizeof(unsigned int) * index;
365     if (allocSize == 0) {
366         HalFree((void *)capsBinded);
367         return PERM_ERRORCODE_SUCCESS;
368     }
369     *caps = (unsigned int *)HalMalloc(allocSize);
370     if (*caps == NULL) {
371         HalFree((void *)capsBinded);
372         return PERM_ERRORCODE_MALLOC_FAIL;
373     }
374     for (int k = 0; k < index; k++) {
375         *(*caps + k) = capsBinded[k];
376     }
377     *capNum = index;
378     HalFree((void *)capsBinded);
379     return PERM_ERRORCODE_SUCCESS;
380 }
381 
UpdateAppPermission(const char * identifier,const PermissionTrans newPerms[],int newPermNum,enum IsUpdate isUpdate)382 static int UpdateAppPermission(
383     const char *identifier, const PermissionTrans newPerms[], int newPermNum, enum IsUpdate isUpdate)
384 {
385     PermissionSaved *permissions = NULL;
386     int permNum = 0;
387     int retCode = PERM_ERRORCODE_SUCCESS;
388     if (isUpdate == UPDATE) {
389         retCode = QueryPermission(identifier, &permissions, &permNum);
390     }
391     if ((retCode != PERM_ERRORCODE_SUCCESS) && (retCode != PERM_ERRORCODE_FILE_NOT_EXIST)) {
392         return retCode;
393     }
394     int allocSize = sizeof(PermissionSaved) * newPermNum;
395     PermissionSaved *updatePerms = (PermissionSaved *)HalMalloc(allocSize);
396     if (updatePerms == NULL) {
397         HalFree((void *)permissions);
398         return PERM_ERRORCODE_MALLOC_FAIL;
399     }
400     for (int i = 0; i < newPermNum; i++) {
401         if (strlen(newPerms[i].name) > PERM_NAME_LEN - 1 || strlen(newPerms[i].desc) > PERM_DESC_LEN - 1) {
402             HalFree((void *)updatePerms);
403             HalFree((void *)permissions);
404             return PERM_ERRORCODE_FIELD_TOO_LONG;
405         }
406         if (strcpy_s(updatePerms[i].name, PERM_NAME_LEN, newPerms[i].name) != EOK) {
407             HalFree((void *)updatePerms);
408             HalFree((void *)permissions);
409             return PERM_ERRORCODE_COPY_ERROR;
410         }
411         if (strcpy_s(updatePerms[i].desc, PERM_DESC_LEN, newPerms[i].desc) != EOK) {
412             HalFree((void *)updatePerms);
413             HalFree((void *)permissions);
414             return PERM_ERRORCODE_COPY_ERROR;
415         }
416         int permType = GetPermissionType(newPerms[i].name);
417         updatePerms[i].granted = NOT_GRANTED;
418         updatePerms[i].flags = PMS_FLAG_DEFAULT;
419         if (permType != PERM_ERRORCODE_INVALID_PERMNAME) {
420             updatePerms[i].granted = (permType == SYSTEM_GRANT) ? GRANTED : NOT_GRANTED;
421         }
422         for (int j = 0; j < permNum; j++) {
423             if (strcmp(newPerms[i].name, (permissions + j)->name) == 0) {
424                 updatePerms[i].granted = permissions[j].granted;
425             }
426         }
427     }
428     retCode = SavePermissions(identifier, updatePerms, newPermNum);
429     HalFree((void *)updatePerms);
430     HalFree((void *)permissions);
431     return retCode;
432 }
433 
SaveOrUpdatePermissions(const char * identifier,PermissionTrans permissions[],int permNum,enum IsUpdate isUpdate)434 int SaveOrUpdatePermissions(
435     const char *identifier, PermissionTrans permissions[], int permNum, enum IsUpdate isUpdate)
436 {
437     if ((identifier == NULL) || (permissions == NULL) || (permNum < 0) ||
438         (isUpdate != UPDATE && isUpdate != FIRST_INSTALL)) {
439         return PERM_ERRORCODE_INVALID_PARAMS;
440     }
441     if (permNum > HalGetMaxPermissionSize()) {
442         return PERM_ERRORCODE_TOO_MUCH_PERM;
443     }
444     char *path = GetPath(identifier);
445     if (path == NULL) {
446         return PERM_ERRORCODE_MALLOC_FAIL;
447     }
448     if (permNum == 0) {
449         unlink(path);
450         HalFree((void *)path);
451         return PERM_ERRORCODE_SUCCESS;
452     }
453     HalFree((void *)path);
454 
455     int distinctNum = 0;
456     int *flag = (int *)HalMalloc(permNum * sizeof(int));
457     if (flag == NULL) {
458         return PERM_ERRORCODE_MALLOC_FAIL;
459     }
460     (void)memset_s(flag, permNum * sizeof(int), 0, permNum * sizeof(int));
461     for (int i = 0; i < permNum; i++) {
462         if (flag[i] != 0) {
463             continue;
464         }
465         permissions[distinctNum++] = permissions[i];
466         for (int j = i + 1; j < permNum; j++) {
467             if (strcmp(permissions[i].name, permissions[j].name) == 0) {
468                 flag[j] = 1;
469             }
470         }
471     }
472     HalFree((void *)flag);
473 
474     return UpdateAppPermission(identifier, permissions, distinctNum, isUpdate);
475 }
476 
DeletePermissions(const char * identifier)477 int DeletePermissions(const char *identifier)
478 {
479     if (identifier == NULL) {
480         return PERM_ERRORCODE_INVALID_PARAMS;
481     }
482     int ret;
483     char *path = NULL;
484     path = GetPath(identifier);
485     if (path == NULL) {
486         return PERM_ERRORCODE_MALLOC_FAIL;
487     }
488 
489     ret = HalAccess(path);
490     if (ret != 0) {
491         HalFree((void *)path);
492         return PERM_ERRORCODE_SUCCESS;
493     }
494 
495     ret = unlink(path);
496     HalFree((void *)path);
497     return (ret != 0) ? PERM_ERRORCODE_UNLINK_ERROR : PERM_ERRORCODE_SUCCESS;
498 }
499 
IsPermissionValid(const char * permissionName)500 int IsPermissionValid(const char *permissionName)
501 {
502     unsigned int permSize = 0;
503     PermissionDef *permList = HalGetPermissionList(&permSize);
504 
505     for (int i = 0; i < permSize; i++) {
506         if (strcmp(permissionName, permList[i].name) == 0) {
507             return PERM_ERRORCODE_SUCCESS;
508         }
509     }
510     return PERM_ERRORCODE_INVALID_PERMNAME;
511 }
512 
IsPermissionRestricted(const char * permissionName)513 int IsPermissionRestricted(const char *permissionName)
514 {
515     unsigned int permSize = 0;
516     PermissionDef *permList = HalGetPermissionList(&permSize);
517 
518     for (int i = 0; i < permSize; i++) {
519         if (strcmp(permissionName, permList[i].name) == 0) {
520             return permList[i].isRestricted;
521         }
522     }
523     return PERM_ERRORCODE_INVALID_PERMNAME;
524 }
525 
LoadPermissions(const char * identifier,int uid)526 int LoadPermissions(const char *identifier, int uid)
527 {
528     if (uid < 0 || identifier == NULL) {
529         return PERM_ERRORCODE_INVALID_PARAMS;
530     }
531 
532     HalMutexLock();
533     TNode *task = GetTaskWithUid(&g_taskList, uid);
534     if (task != NULL) {
535         HalMutexUnlock();
536         return PERM_ERRORCODE_SUCCESS;
537     }
538 
539     PermissionSaved *permissions = NULL;
540     int permNum = 0;
541     int ret = QueryPermission(identifier, &permissions, &permNum);
542     if (ret == PERM_ERRORCODE_FILE_NOT_EXIST) {
543         HILOG_ERROR(HILOG_MODULE_APP, "Perm file not exists.");
544         HalMutexUnlock();
545         return PERM_ERRORCODE_SUCCESS;
546     }
547     if (ret != PERM_ERRORCODE_SUCCESS) {
548         HalMutexUnlock();
549         return ret;
550     }
551     TNode *node = (TNode *)HalMalloc(sizeof(TNode));
552     if (node == NULL) {
553         HalFree((void *)permissions);
554         HalMutexUnlock();
555         return PERM_ERRORCODE_MALLOC_FAIL;
556     }
557     node->uid = uid;
558     if (strcpy_s(node->pkgName, PKG_NAME_LEN, identifier) != EOK) {
559         HalFree((void *)permissions);
560         HalFree((void *)node);
561         HalMutexUnlock();
562         return PERM_ERRORCODE_COPY_ERROR;
563     }
564     node->permList = permissions;
565     node->permNum = permNum;
566     node->next = NULL;
567 
568     AddTask(&g_taskList, node);
569     HalMutexUnlock();
570 
571     return PERM_ERRORCODE_SUCCESS;
572 }
573 
UnLoadPermissions(int uid)574 int UnLoadPermissions(int uid)
575 {
576     HalMutexLock();
577     DeleteTask(&g_taskList, uid);
578     HalMutexUnlock();
579     return PERM_ERRORCODE_SUCCESS;
580 }
581 
CheckPermissionStat(int uid,const char * permissionName)582 int CheckPermissionStat(int uid, const char *permissionName)
583 {
584     if (uid < 0 || permissionName == NULL) {
585         return PERM_ERRORCODE_INVALID_PARAMS;
586     }
587     HalMutexLock();
588     int ret = PermissionIsGranted(&g_taskList, uid, permissionName);
589     HalMutexUnlock();
590     return ret;
591 }
592 
OnPermissionFileSync(const char * identifier,const char * permName,const enum IsGranted granted)593 static int OnPermissionFileSync(const char *identifier, const char *permName, const enum IsGranted granted)
594 {
595     int retCode = PERM_ERRORCODE_SUCCESS;
596     bool isSave = false;
597     PermissionSaved *permissions = NULL;
598     int permNum = 0;
599     int ret = QueryPermission(identifier, &permissions, &permNum);
600     if (ret != PERM_ERRORCODE_SUCCESS) {
601         return ret;
602     }
603     for (int i = 0; i < permNum; i++) {
604         if (strcmp(permissions[i].name, permName) == 0) {
605             isSave = permissions[i].granted ^ granted;
606             permissions[i].granted = granted;
607             break;
608         }
609     }
610     if (isSave) {
611         retCode = SavePermissions(identifier, permissions, permNum);
612     }
613     HalFree((void *)permissions);
614     return retCode;
615 }
616 
OnPermissionFlagsFileSync(const char * identifier,const char * permName,const int flags)617 static int OnPermissionFlagsFileSync(const char *identifier, const char *permName, const int flags)
618 {
619     int retCode = PERM_ERRORCODE_SUCCESS;
620     bool isSave = false;
621     PermissionSaved *permissions = NULL;
622     int permNum = 0;
623     int ret = QueryPermission(identifier, &permissions, &permNum);
624     if (ret != PERM_ERRORCODE_SUCCESS) {
625         return ret;
626     }
627     for (int i = 0; i < permNum; i++) {
628         if (strcmp(permissions[i].name, permName) == 0) {
629             isSave = permissions[i].flags ^ flags;
630             permissions[i].flags = flags;
631             break;
632         }
633     }
634     if (isSave) {
635         retCode = SavePermissions(identifier, permissions, permNum);
636     }
637     HalFree((void *)permissions);
638     return retCode;
639 }
640 
GrantPermission(const char * identifier,const char * permName)641 int GrantPermission(const char *identifier, const char *permName)
642 {
643     if ((identifier == NULL) || (permName == NULL)) {
644         return PERM_ERRORCODE_INVALID_PARAMS;
645     }
646     int ret = PERM_ERRORCODE_SUCCESS;
647     HalMutexLock();
648     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
649     if (node != NULL) {
650         ret = ModifyPermission(node, permName, GRANTED);
651     }
652     HalMutexUnlock();
653 
654     if (ret != 0) {
655         return PERM_ERRORCODE_PERM_NOT_EXIST;
656     }
657 
658     return OnPermissionFileSync(identifier, permName, GRANTED);
659 }
660 
RevokePermission(const char * identifier,const char * permName)661 int RevokePermission(const char *identifier, const char *permName)
662 {
663     if ((identifier == NULL) || (permName == NULL)) {
664         return PERM_ERRORCODE_INVALID_PARAMS;
665     }
666     int ret = PERM_ERRORCODE_SUCCESS;
667     HalMutexLock();
668     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
669     if (node != NULL) {
670         ret = ModifyPermission(node, permName, NOT_GRANTED);
671     }
672     HalMutexUnlock();
673 
674     if (ret != 0) {
675         return PERM_ERRORCODE_PERM_NOT_EXIST;
676     }
677 
678     return OnPermissionFileSync(identifier, permName, NOT_GRANTED);
679 }
680 
GrantRuntimePermission(int uid,const char * permissionName)681 int GrantRuntimePermission(int uid, const char *permissionName)
682 {
683     if (permissionName == NULL) {
684         return PERM_ERRORCODE_INVALID_PARAMS;
685     }
686 
687     HalMutexLock();
688     TNode *node = GetTaskWithUid(&g_taskList, uid);
689     if (node == NULL) {
690         HalMutexUnlock();
691         return PERM_ERRORCODE_TASKID_NOT_EXIST;
692     }
693 
694     int ret = ModifyPermission(node, permissionName, GRANTED);
695     HalMutexUnlock();
696     if (ret < 0) {
697         return PERM_ERRORCODE_PERM_NOT_EXIST;
698     }
699 
700     return OnPermissionFileSync(node->pkgName, permissionName, GRANTED);
701 }
702 
RevokeRuntimePermission(int uid,const char * permissionName)703 int RevokeRuntimePermission(int uid, const char *permissionName)
704 {
705     if (permissionName == NULL) {
706         return PERM_ERRORCODE_INVALID_PARAMS;
707     }
708 
709     HalMutexLock();
710     TNode *node = GetTaskWithUid(&g_taskList, uid);
711     if (node == NULL) {
712         HalMutexUnlock();
713         return PERM_ERRORCODE_TASKID_NOT_EXIST;
714     }
715 
716     int ret = ModifyPermission(node, permissionName, NOT_GRANTED);
717     HalMutexUnlock();
718     if (ret < 0) {
719         return PERM_ERRORCODE_PERM_NOT_EXIST;
720     }
721 
722     return OnPermissionFileSync(node->pkgName, permissionName, NOT_GRANTED);
723 }
724 
UpdatePermissionFlags(const char * identifier,const char * permissionName,const int flags)725 int UpdatePermissionFlags(const char *identifier, const char *permissionName, const int flags)
726 {
727     if ((identifier == NULL) || (permissionName == NULL) || !IsValidFlags(flags)) {
728         return PERM_ERRORCODE_INVALID_PARAMS;
729     }
730 
731     return OnPermissionFlagsFileSync(identifier, permissionName, flags);
732 }
733