Split APIs not to access DB while trying to access DB
[platform/core/security/privilege-checker.git] / capi / src / privilege_package_info.c
1 /*
2  * Copyright(c) 2017-2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0(the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <dlog.h>
19 #include <glib.h>
20 #include <pkgmgr-info.h>
21
22 #include "privilege_db_manager.h"
23 #include "privilege_private.h"
24 #include "privilege_package_info.h"
25
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #define LOG_TAG "PRIVILEGE_PACKAGE_INFO"
29 #endif
30
31 #define TryReturn(condition, expr, returnValue, ...)    \
32         if (!(condition)) { \
33                 LOGE(__VA_ARGS__); \
34                 expr; \
35                 return returnValue;     \
36         }
37
38 static int __get_user_settable_privilege_privacy_info_list(const char* pkgid, privilege_manager_package_type_e pkg_type, const char* api_version, GList *privilege_list, GList **privilege_privacy_info_list)
39 {
40         GList *mapped_privilege_list = NULL;
41         int ret = privilege_db_manager_get_mapped_privilege_list(api_version, pkg_type, privilege_list, &mapped_privilege_list);
42         TryReturn(ret == PRIVILEGE_DB_MANAGER_ERR_NONE && mapped_privilege_list != NULL, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] privilege_db_manager_get_mapped_privilege_list() failed. ret = %d", ret);
43
44         ret = privilege_db_manager_get_privacy_filtered_privilege_info_list(mapped_privilege_list, NULL, privilege_privacy_info_list);
45         privilege_db_manager_list_free(mapped_privilege_list);
46         TryReturn(ret == PRIVILEGE_DB_MANAGER_ERR_NONE, ,PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] privilege_db_manager_get_privacy_filtered_privilege_info_list() failed. ret = %d", ret);
47
48         GList *ll = NULL;
49         for (GList *l = *privilege_privacy_info_list; l != NULL; l = ll, ret = PRVMGR_ERR_NONE) {
50                 ll = l->next;
51                 int privacy_id = -1;
52                 const char* privilege = (const char*)((privilege_privacy_info_s*)l->data)->privilege_name;
53                 ret = privilege_db_manager_get_privacy_id_by_privilege(privilege, &privacy_id);
54                 if (ret == PRIVILEGE_DB_MANAGER_ERR_NONE && privacy_id != -1) {
55                         ret = privilege_db_manager_is_user_settable(pkgid, privacy_id);
56                         if (ret == 1) {
57                                 continue;
58                         } else if (ret == 0) {
59                                 privilege_privacy_info_s* tmp = l->data;
60                                 *privilege_privacy_info_list = g_list_remove(*privilege_privacy_info_list, tmp);
61                                 free_privilege_privacy_info(tmp);
62                         } else {
63                                 LOGE("privilege_db_manager_is_user_settable(%s, %d) failed. ret = %d", pkgid, privacy_id, ret);
64                                 ret = PRVMGR_ERR_INTERNAL_ERROR;
65                                 break;
66                         }
67                 } else {
68                         LOGE("privilege_db_manager_get_privacy_id_by_privilege() failed. privilege = %s. ret = %d", privilege, ret);
69                         ret = PRVMGR_ERR_INTERNAL_ERROR;
70                         break;
71                 }
72         }
73         return ret;
74 }
75
76 int privilege_package_info_set_privacy_privilege(const uid_t uid, const char* pkgid, privilege_manager_package_type_e pkg_type, const char* api_version, GList* privilege_list)
77 {
78         if (DISABLE_ASKUSER)
79                 return PRVMGR_ERR_NONE;
80         TryReturn(pkgid != NULL && api_version != NULL && privilege_list != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid, api_version, and privilege_list must not be NULL.");
81
82         GList *privilege_privacy_info_list = NULL;
83         int ret = __get_user_settable_privilege_privacy_info_list(pkgid, pkg_type, api_version, privilege_list, &privilege_privacy_info_list);
84         TryReturn(ret == PRVMGR_ERR_NONE, , PRVMGR_ERR_INTERNAL_ERROR, "__get_user_settable_privilege_privacy_info_list() failed. ret = %d", ret);
85
86         if (privilege_privacy_info_list == NULL) {
87                 LOGD("%s have no user-settable privacy privilege", pkgid);
88                 return PRVMGR_ERR_NONE;
89         }
90
91         ret = privilege_db_manager_set_package_privacy_privilege_info(uid, pkgid, api_version, privilege_privacy_info_list);
92         free_privilege_privacy_info_list(privilege_privacy_info_list);
93
94         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
95                 LOGE("privilege_db_manager_set_package_privacy_privilege_info failed. ret = %d", ret);
96                 return PRVMGR_ERR_INTERNAL_ERROR;
97         }
98         return PRVMGR_ERR_NONE;
99 }
100
101 int privilege_package_info_unset_package_privilege_info(const uid_t uid, const char* pkgid)
102 {
103         if (DISABLE_ASKUSER)
104                 return PRVMGR_ERR_NONE;
105
106         TryReturn(pkgid != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid must not be NULL.");
107         int ret = privilege_db_manager_unset_package_privilege_info(uid, pkgid);
108         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
109                 LOGE("privilege_db_manager_unset_package_privilege_info failed. ret = %d", ret);
110                 return PRVMGR_ERR_INTERNAL_ERROR;
111         }
112         return PRVMGR_ERR_NONE;
113 }
114
115 static int __get_pkg_type(uid_t uid, const char *pkgid, privilege_manager_package_type_e *pkg_type)
116 {
117         int ret = 0;
118         char *type = NULL;
119         pkgmgrinfo_pkginfo_h handle = NULL;
120         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
121         if (ret != PMINFO_R_OK) {
122                 LOGE("failed to get pkginfo handle! pkgid <%s>", pkgid);
123                 return -1;
124         }
125         ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
126         if (ret != PMINFO_R_OK) {
127                 LOGE("failed to get type, pkgid <%s>", pkgid);
128                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
129                 return -1;
130         }
131         if (strcmp(type, "wgt") == 0)
132                 *pkg_type = PRVMGR_PACKAGE_TYPE_WRT;
133         else
134                 *pkg_type = PRVMGR_PACKAGE_TYPE_CORE;
135         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
136         return 0;
137 }
138
139 static bool __is_disabled_package(uid_t uid, const char *pkgid)
140 {
141         pkgmgrinfo_pkginfo_h handle = NULL;
142         int ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgid, uid, &handle);
143
144         if (handle != NULL)
145                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
146
147         if (ret == PMINFO_R_OK) {
148                 return true;
149         } else {
150                 return false;
151         }
152 }
153
154 int privilege_package_info_is_privacy_requestable(const uid_t uid, const char* pkgid, const char* privilege, bool* is_requestable)
155 {
156         TryReturn(pkgid != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid must not be NULL.");
157
158         privilege_manager_package_type_e pkg_type = PRVMGR_PACKAGE_TYPE_NONE;
159         int ret = __get_pkg_type(uid, pkgid, &pkg_type);
160         TryReturn(ret == 0 && pkg_type != PRVMGR_PACKAGE_TYPE_NONE, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] failed to get pkg type of <%s>", pkgid);
161         ret = privilege_db_manager_is_privacy_requestable(uid, pkgid, privilege, pkg_type, is_requestable);
162
163         if (ret == PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT) { // CASE: given pkgid have no privacy privileges
164                 *is_requestable = false;
165         } else if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
166                 LOGE("privilege_db_manager_is_privacy_requestable_package failed. ret = %d", ret);
167                 return PRVMGR_ERR_INTERNAL_ERROR;
168         }
169         return PRVMGR_ERR_NONE;
170 }
171
172 int privilege_package_info_get_all_privacy_package_list(const uid_t uid, GList** privacy_list)
173 {
174         int ret = privilege_db_manager_get_all_privacy_package_list(uid, privacy_list);
175         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE && ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT) {
176                 LOGE("privilege_db_manager_get_all_privacy_package_list failed. ret = %d", ret);
177                 return PRVMGR_ERR_INTERNAL_ERROR;
178         }
179
180         GList *l = NULL;
181         for(l = *privacy_list; l != NULL;) {  // Remove disabled packages
182                 GList *ll = l->next;
183                 if (__is_disabled_package(uid, (const char*)l->data)) {
184                         LOGD("uid = %d, pkgid = %s is disabled package. Remove.", uid, (char*)l->data);
185                         *privacy_list = g_list_remove(*privacy_list, l->data);
186                 }
187                 l = ll;
188         }
189
190         return PRVMGR_ERR_NONE;
191 }
192
193 int privilege_package_info_get_privacy_list_by_pkgid(const uid_t uid, const char* pkgid, GList** privacy_list)
194 {
195         TryReturn(pkgid != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid must not be null");
196         int ret = privilege_db_manager_get_privacy_list_by_pkgid(uid, pkgid, privacy_list);
197         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE && ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT) {
198                 LOGE("privilege_db_manager_get_privacy_list_by_pkgid failed. ret = %d", ret);
199                 return PRVMGR_ERR_INTERNAL_ERROR;
200         }
201         return PRVMGR_ERR_NONE;
202 }
203
204 int privilege_package_info_get_package_list_by_privacy(const uid_t uid, const char* privacy, GList** package_list)
205 {
206         TryReturn(privacy != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] privacy must not be null");
207         int ret = privilege_db_manager_get_package_list_by_privacy(uid, privacy, package_list);
208         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE && ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT) {
209                 LOGE("privilege_db_manager_get_package_list_by_privacy failed. ret = %d", ret);
210                 return PRVMGR_ERR_INTERNAL_ERROR;
211         }
212
213         GList *l = NULL;
214         for(l = *package_list; l != NULL;) {  // Remove disabled packages
215                 GList *ll = l->next;
216                 if (__is_disabled_package(uid, (const char*)l->data)) {
217                         LOGD("uid = %d, pkgid = %s is disabled package. Remove.", uid, (char*)l->data);
218                         *package_list = g_list_remove(*package_list, l->data);
219                 }
220                 l = ll;
221         }
222         return PRVMGR_ERR_NONE;
223 }
224
225 int privilege_package_info_get_privilege_list_by_pkgid_and_privacy(const uid_t uid, const char* pkgid, const char* privacy, GList** privilege_list)
226 {
227         TryReturn(pkgid != NULL && privacy != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] pkgid and privacy must not be null");
228         int ret = privilege_db_manager_get_privilege_list_by_pkgid_and_privacy(uid, pkgid, privacy, privilege_list);
229         if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE && ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT) {
230                 LOGE("privilege_db_manager_get_privilege_list_by_pkgid_and_privacy failed. ret = %d", ret);
231                 return PRVMGR_ERR_INTERNAL_ERROR;
232         }
233         return PRVMGR_ERR_NONE;
234 }