• 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             index++;
361             break;
362         }
363     }
364     HalFree((void *)permissions);
365     allocSize = sizeof(unsigned int) * index;
366     if (allocSize == 0) {
367         HalFree((void *)capsBinded);
368         return PERM_ERRORCODE_SUCCESS;
369     }
370     *caps = (unsigned int *)HalMalloc(allocSize);
371     if (*caps == NULL) {
372         HalFree((void *)capsBinded);
373         return PERM_ERRORCODE_MALLOC_FAIL;
374     }
375     for (int k = 0; k < index; k++) {
376         *(*caps + k) = capsBinded[k];
377     }
378     *capNum = index;
379     HalFree((void *)capsBinded);
380     return PERM_ERRORCODE_SUCCESS;
381 }
382 
UpdateAppPermission(const char * identifier,const PermissionTrans newPerms[],int newPermNum,enum IsUpdate isUpdate)383 static int UpdateAppPermission(
384     const char *identifier, const PermissionTrans newPerms[], int newPermNum, enum IsUpdate isUpdate)
385 {
386     PermissionSaved *permissions = NULL;
387     int permNum = 0;
388     int retCode = PERM_ERRORCODE_SUCCESS;
389     if (isUpdate == UPDATE) {
390         retCode = QueryPermission(identifier, &permissions, &permNum);
391     }
392     if ((retCode != PERM_ERRORCODE_SUCCESS) && (retCode != PERM_ERRORCODE_FILE_NOT_EXIST)) {
393         return retCode;
394     }
395     int allocSize = sizeof(PermissionSaved) * newPermNum;
396     PermissionSaved *updatePerms = (PermissionSaved *)HalMalloc(allocSize);
397     if (updatePerms == NULL) {
398         HalFree((void *)permissions);
399         return PERM_ERRORCODE_MALLOC_FAIL;
400     }
401     for (int i = 0; i < newPermNum; i++) {
402         if (strlen(newPerms[i].name) > PERM_NAME_LEN - 1 || strlen(newPerms[i].desc) > PERM_DESC_LEN - 1) {
403             HalFree((void *)updatePerms);
404             HalFree((void *)permissions);
405             return PERM_ERRORCODE_FIELD_TOO_LONG;
406         }
407         if (strcpy_s(updatePerms[i].name, PERM_NAME_LEN, newPerms[i].name) != EOK) {
408             HalFree((void *)updatePerms);
409             HalFree((void *)permissions);
410             return PERM_ERRORCODE_COPY_ERROR;
411         }
412         if (strcpy_s(updatePerms[i].desc, PERM_DESC_LEN, newPerms[i].desc) != EOK) {
413             HalFree((void *)updatePerms);
414             HalFree((void *)permissions);
415             return PERM_ERRORCODE_COPY_ERROR;
416         }
417         int permType = GetPermissionType(newPerms[i].name);
418         updatePerms[i].granted = NOT_GRANTED;
419         updatePerms[i].flags = PMS_FLAG_DEFAULT;
420         if (permType != PERM_ERRORCODE_INVALID_PERMNAME) {
421             updatePerms[i].granted = (permType == SYSTEM_GRANT) ? GRANTED : NOT_GRANTED;
422         }
423         for (int j = 0; j < permNum; j++) {
424             if (strcmp(newPerms[i].name, (permissions + j)->name) == 0) {
425                 updatePerms[i].granted = permissions[j].granted;
426             }
427         }
428     }
429     retCode = SavePermissions(identifier, updatePerms, newPermNum);
430     HalFree((void *)updatePerms);
431     HalFree((void *)permissions);
432     return retCode;
433 }
434 
SaveOrUpdatePermissions(const char * identifier,PermissionTrans permissions[],int permNum,enum IsUpdate isUpdate)435 int SaveOrUpdatePermissions(
436     const char *identifier, PermissionTrans permissions[], int permNum, enum IsUpdate isUpdate)
437 {
438     if ((identifier == NULL) || (permissions == NULL) || (permNum < 0) ||
439         (isUpdate != UPDATE && isUpdate != FIRST_INSTALL)) {
440         return PERM_ERRORCODE_INVALID_PARAMS;
441     }
442     if (permNum > HalGetMaxPermissionSize()) {
443         return PERM_ERRORCODE_TOO_MUCH_PERM;
444     }
445     char *path = GetPath(identifier);
446     if (path == NULL) {
447         return PERM_ERRORCODE_MALLOC_FAIL;
448     }
449     if (permNum == 0) {
450         unlink(path);
451         HalFree((void *)path);
452         return PERM_ERRORCODE_SUCCESS;
453     }
454     HalFree((void *)path);
455 
456     int distinctNum = 0;
457     int *flag = (int *)HalMalloc(permNum * sizeof(int));
458     if (flag == NULL) {
459         return PERM_ERRORCODE_MALLOC_FAIL;
460     }
461     (void)memset_s(flag, permNum * sizeof(int), 0, permNum * sizeof(int));
462     for (int i = 0; i < permNum; i++) {
463         if (flag[i] != 0) {
464             continue;
465         }
466         permissions[distinctNum++] = permissions[i];
467         for (int j = i + 1; j < permNum; j++) {
468             if (strcmp(permissions[i].name, permissions[j].name) == 0) {
469                 flag[j] = 1;
470             }
471         }
472     }
473     HalFree((void *)flag);
474 
475     return UpdateAppPermission(identifier, permissions, distinctNum, isUpdate);
476 }
477 
DeletePermissions(const char * identifier)478 int DeletePermissions(const char *identifier)
479 {
480     if (identifier == NULL) {
481         return PERM_ERRORCODE_INVALID_PARAMS;
482     }
483     int ret;
484     char *path = NULL;
485     path = GetPath(identifier);
486     if (path == NULL) {
487         return PERM_ERRORCODE_MALLOC_FAIL;
488     }
489 
490     ret = HalAccess(path);
491     if (ret != 0) {
492         HalFree((void *)path);
493         return PERM_ERRORCODE_SUCCESS;
494     }
495 
496     ret = unlink(path);
497     HalFree((void *)path);
498     return (ret != 0) ? PERM_ERRORCODE_UNLINK_ERROR : PERM_ERRORCODE_SUCCESS;
499 }
500 
IsPermissionValid(const char * permissionName)501 int IsPermissionValid(const char *permissionName)
502 {
503     unsigned int permSize = 0;
504     PermissionDef *permList = HalGetPermissionList(&permSize);
505 
506     for (int i = 0; i < permSize; i++) {
507         if (strcmp(permissionName, permList[i].name) == 0) {
508             return PERM_ERRORCODE_SUCCESS;
509         }
510     }
511     return PERM_ERRORCODE_INVALID_PERMNAME;
512 }
513 
IsPermissionRestricted(const char * permissionName)514 int IsPermissionRestricted(const char *permissionName)
515 {
516     unsigned int permSize = 0;
517     PermissionDef *permList = HalGetPermissionList(&permSize);
518 
519     for (int i = 0; i < permSize; i++) {
520         if (strcmp(permissionName, permList[i].name) == 0) {
521             return permList[i].isRestricted;
522         }
523     }
524     return PERM_ERRORCODE_INVALID_PERMNAME;
525 }
526 
LoadPermissions(const char * identifier,int uid)527 int LoadPermissions(const char *identifier, int uid)
528 {
529     if (uid < 0 || identifier == NULL) {
530         return PERM_ERRORCODE_INVALID_PARAMS;
531     }
532 
533     HalMutexLock();
534     TNode *task = GetTaskWithUid(&g_taskList, uid);
535     if (task != NULL) {
536         HalMutexUnlock();
537         return PERM_ERRORCODE_SUCCESS;
538     }
539 
540     PermissionSaved *permissions = NULL;
541     int permNum = 0;
542     int ret = QueryPermission(identifier, &permissions, &permNum);
543     if (ret == PERM_ERRORCODE_FILE_NOT_EXIST) {
544         HILOG_ERROR(HILOG_MODULE_APP, "Perm file not exists.");
545         HalMutexUnlock();
546         return PERM_ERRORCODE_SUCCESS;
547     }
548     if (ret != PERM_ERRORCODE_SUCCESS) {
549         HalMutexUnlock();
550         return ret;
551     }
552     TNode *node = (TNode *)HalMalloc(sizeof(TNode));
553     if (node == NULL) {
554         HalFree((void *)permissions);
555         HalMutexUnlock();
556         return PERM_ERRORCODE_MALLOC_FAIL;
557     }
558     node->uid = uid;
559     if (strcpy_s(node->pkgName, PKG_NAME_LEN, identifier) != EOK) {
560         HalFree((void *)permissions);
561         HalFree((void *)node);
562         HalMutexUnlock();
563         return PERM_ERRORCODE_COPY_ERROR;
564     }
565     node->permList = permissions;
566     node->permNum = permNum;
567     node->next = NULL;
568 
569     AddTask(&g_taskList, node);
570     HalMutexUnlock();
571 
572     return PERM_ERRORCODE_SUCCESS;
573 }
574 
UnLoadPermissions(int uid)575 int UnLoadPermissions(int uid)
576 {
577     HalMutexLock();
578     DeleteTask(&g_taskList, uid);
579     HalMutexUnlock();
580     return PERM_ERRORCODE_SUCCESS;
581 }
582 
CheckPermissionStat(int uid,const char * permissionName)583 int CheckPermissionStat(int uid, const char *permissionName)
584 {
585     if (uid < 0 || permissionName == NULL) {
586         return PERM_ERRORCODE_INVALID_PARAMS;
587     }
588     HalMutexLock();
589     int ret = PermissionIsGranted(&g_taskList, uid, permissionName);
590     HalMutexUnlock();
591     return ret;
592 }
593 
OnPermissionFileSync(const char * identifier,const char * permName,const enum IsGranted granted)594 static int OnPermissionFileSync(const char *identifier, const char *permName, const enum IsGranted granted)
595 {
596     int retCode = PERM_ERRORCODE_SUCCESS;
597     bool isSave = false;
598     PermissionSaved *permissions = NULL;
599     int permNum = 0;
600     int ret = QueryPermission(identifier, &permissions, &permNum);
601     if (ret != PERM_ERRORCODE_SUCCESS) {
602         return ret;
603     }
604     for (int i = 0; i < permNum; i++) {
605         if (strcmp(permissions[i].name, permName) == 0) {
606             isSave = permissions[i].granted ^ granted;
607             permissions[i].granted = granted;
608             break;
609         }
610     }
611     if (isSave) {
612         retCode = SavePermissions(identifier, permissions, permNum);
613     }
614     HalFree((void *)permissions);
615     return retCode;
616 }
617 
OnPermissionFlagsFileSync(const char * identifier,const char * permName,const int flags)618 static int OnPermissionFlagsFileSync(const char *identifier, const char *permName, const int flags)
619 {
620     int retCode = PERM_ERRORCODE_SUCCESS;
621     bool isSave = false;
622     PermissionSaved *permissions = NULL;
623     int permNum = 0;
624     int ret = QueryPermission(identifier, &permissions, &permNum);
625     if (ret != PERM_ERRORCODE_SUCCESS) {
626         return ret;
627     }
628     for (int i = 0; i < permNum; i++) {
629         if (strcmp(permissions[i].name, permName) == 0) {
630             isSave = permissions[i].flags ^ flags;
631             permissions[i].flags = flags;
632             break;
633         }
634     }
635     if (isSave) {
636         retCode = SavePermissions(identifier, permissions, permNum);
637     }
638     HalFree((void *)permissions);
639     return retCode;
640 }
641 
GrantPermission(const char * identifier,const char * permName)642 int GrantPermission(const char *identifier, const char *permName)
643 {
644     if ((identifier == NULL) || (permName == NULL)) {
645         return PERM_ERRORCODE_INVALID_PARAMS;
646     }
647     int ret = PERM_ERRORCODE_SUCCESS;
648     HalMutexLock();
649     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
650     if (node != NULL) {
651         ret = ModifyPermission(node, permName, GRANTED);
652     }
653     HalMutexUnlock();
654 
655     if (ret != 0) {
656         return PERM_ERRORCODE_PERM_NOT_EXIST;
657     }
658 
659     return OnPermissionFileSync(identifier, permName, GRANTED);
660 }
661 
RevokePermission(const char * identifier,const char * permName)662 int RevokePermission(const char *identifier, const char *permName)
663 {
664     if ((identifier == NULL) || (permName == NULL)) {
665         return PERM_ERRORCODE_INVALID_PARAMS;
666     }
667     int ret = PERM_ERRORCODE_SUCCESS;
668     HalMutexLock();
669     TNode *node = GetTaskWithPkgName(&g_taskList, identifier);
670     if (node != NULL) {
671         ret = ModifyPermission(node, permName, NOT_GRANTED);
672     }
673     HalMutexUnlock();
674 
675     if (ret != 0) {
676         return PERM_ERRORCODE_PERM_NOT_EXIST;
677     }
678 
679     return OnPermissionFileSync(identifier, permName, NOT_GRANTED);
680 }
681 
GrantRuntimePermission(int uid,const char * permissionName)682 int GrantRuntimePermission(int uid, const char *permissionName)
683 {
684     if (permissionName == NULL) {
685         return PERM_ERRORCODE_INVALID_PARAMS;
686     }
687 
688     HalMutexLock();
689     TNode *node = GetTaskWithUid(&g_taskList, uid);
690     if (node == NULL) {
691         HalMutexUnlock();
692         return PERM_ERRORCODE_TASKID_NOT_EXIST;
693     }
694 
695     int ret = ModifyPermission(node, permissionName, GRANTED);
696     HalMutexUnlock();
697     if (ret < 0) {
698         return PERM_ERRORCODE_PERM_NOT_EXIST;
699     }
700 
701     return OnPermissionFileSync(node->pkgName, permissionName, GRANTED);
702 }
703 
RevokeRuntimePermission(int uid,const char * permissionName)704 int RevokeRuntimePermission(int uid, const char *permissionName)
705 {
706     if (permissionName == NULL) {
707         return PERM_ERRORCODE_INVALID_PARAMS;
708     }
709 
710     HalMutexLock();
711     TNode *node = GetTaskWithUid(&g_taskList, uid);
712     if (node == NULL) {
713         HalMutexUnlock();
714         return PERM_ERRORCODE_TASKID_NOT_EXIST;
715     }
716 
717     int ret = ModifyPermission(node, permissionName, NOT_GRANTED);
718     HalMutexUnlock();
719     if (ret < 0) {
720         return PERM_ERRORCODE_PERM_NOT_EXIST;
721     }
722 
723     return OnPermissionFileSync(node->pkgName, permissionName, NOT_GRANTED);
724 }
725 
UpdatePermissionFlags(const char * identifier,const char * permissionName,const int flags)726 int UpdatePermissionFlags(const char *identifier, const char *permissionName, const int flags)
727 {
728     if ((identifier == NULL) || (permissionName == NULL) || !IsValidFlags(flags)) {
729         return PERM_ERRORCODE_INVALID_PARAMS;
730     }
731 
732     return OnPermissionFlagsFileSync(identifier, permissionName, flags);
733 }
734