Add privilege check logic.
[platform/core/api/package-manager.git] / src / package_manager_internal.c
1 /*
2  * Copyright (c) 2011 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 <unistd.h>
18
19 #include <pkgmgr-info.h>
20 #include <tzplatform_config.h>
21 #include <cynara-client.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24
25 #include "package_info.h"
26 #include "package_manager.h"
27 #include "package_manager_internal.h"
28
29 #define SMACK_LABEL_LEN 255
30 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
31
32 typedef struct _foreach_pkg_context_{
33         package_manager_package_info_cb callback;
34         void *user_data;
35 } foreach_pkg_context_s;
36
37 int check_privilege(privilege_type type) {
38
39         cynara *p_cynara;
40
41         int fd = 0;
42         int ret = 0;
43
44         char subject_label[SMACK_LABEL_LEN + 1] = "";
45         char uid[10] = {0,};
46         char *client_session = "";
47
48         ret = cynara_initialize(&p_cynara, NULL);
49         if (ret != CYNARA_API_SUCCESS) {
50                 LOGE("cannot init cynara [%d] failed!", ret);
51                 ret = PACKAGE_MANAGER_ERROR_IO_ERROR;
52                 goto out;
53         }
54
55         fd = open("/proc/self/attr/current", O_RDONLY);
56         if (fd < 0) {
57                 LOGE("open [%d] failed!", errno);
58                 ret = PACKAGE_MANAGER_ERROR_IO_ERROR;
59                 goto out;
60         }
61
62         ret = read(fd, subject_label, SMACK_LABEL_LEN);
63         if (ret < 0) {
64                 LOGE("read [%d] failed!", errno);
65                 close(fd);
66                 ret = PACKAGE_MANAGER_ERROR_IO_ERROR;
67                 goto out;
68         }
69         close(fd);
70
71         snprintf(uid, 10, "%d", getuid());
72
73         if (type == PRIVILEGE_PACKAGE_MANAGER_INFO) {
74                 ret = cynara_check(p_cynara, subject_label, client_session, uid,
75                                 "http://tizen.org/privilege/packagemanager.info");
76                 if (ret != CYNARA_API_ACCESS_ALLOWED) {
77                         LOGE("cynara access check [%d] failed!", ret);
78                         ret = PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
79                         goto out;
80                 }
81         } else if (type == PRIVILEGE_PACKAGE_MANAGER_ADMIN) {
82                 ret = cynara_check(p_cynara, subject_label, client_session, uid,
83                                 "http://tizen.org/privilege/packagemanager.admin");
84                 if (ret != CYNARA_API_ACCESS_ALLOWED) {
85                         LOGE("cynara access check [%d] failed!", ret);
86                         ret = PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
87                         goto out;
88                 }
89         } else if (type == PRIVILEGE_PACKAGE_MANAGER_CACHE) {
90                 ret = cynara_check(p_cynara, subject_label, client_session, uid,
91                                 "http://tizen.org/privilege/packagemanager.clearcache");
92                 if (ret != CYNARA_API_ACCESS_ALLOWED) {
93                         LOGE("cynara access check [%d] failed!", ret);
94                         ret = PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
95                         goto out;
96                 }
97         }
98
99         ret = PACKAGE_MANAGER_ERROR_NONE;
100 out:
101         if (p_cynara)
102                 cynara_finish(p_cynara);
103
104         return ret;
105 }
106
107 static const char *package_manager_error_to_string(package_manager_error_e
108                                                    error)
109 {
110         switch (error) {
111         case PACKAGE_MANAGER_ERROR_NONE:
112                 return "NONE";
113         case PACKAGE_MANAGER_ERROR_INVALID_PARAMETER:
114                 return "INVALID_PARAMETER";
115         case PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY:
116                 return "OUT_OF_MEMORY";
117         case PACKAGE_MANAGER_ERROR_IO_ERROR:
118                 return "IO_ERROR";
119         case PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE:
120                 return "NO_SUCH_PACKAGE";
121         case PACKAGE_MANAGER_ERROR_PERMISSION_DENIED:
122                 return "PERMISSION_DENIED";
123         case PACKAGE_MANAGER_ERROR_SYSTEM_ERROR:
124                 return "SEVERE_SYSTEM_ERROR";
125         default:
126                 return "UNKNOWN";
127         }
128 }
129
130 int package_manager_error(package_manager_error_e error,
131                                  const char *function, const char *description)
132 {
133         if (description) {
134                 _LOGE("[%s] %s(0x%08x) : %s", function,
135                      package_manager_error_to_string(error), error,
136                      description);
137         } else {
138                 _LOGE("[%s] %s(0x%08x)", function,
139                      package_manager_error_to_string(error), error);
140         }
141
142         return error;
143 }
144
145 int package_info_get_package_info(const char *package, package_info_h *package_info)
146 {
147         return package_info_create(package, package_info);
148 }
149
150 static int package_info_foreach_package_info_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
151 {
152         char *pkg_name = NULL;
153         foreach_pkg_context_s *foreach_pkg_context = user_data;
154         package_info_h package_info = NULL;
155         bool r = false;
156
157         if (handle == NULL || foreach_pkg_context == NULL)
158         {
159                 package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
160                 return PMINFO_R_EINVAL;
161         }
162
163         pkgmgrinfo_pkginfo_get_pkgname(handle, &pkg_name);
164
165         if (package_info_create(pkg_name, &package_info) == PACKAGE_MANAGER_ERROR_NONE)
166         {
167                 r = foreach_pkg_context->callback(package_info, foreach_pkg_context->user_data);
168                 package_info_destroy(package_info);
169         }
170
171         return (r == true) ? PMINFO_R_OK : PMINFO_R_ERROR;
172 }
173
174 int package_info_foreach_package_info(package_manager_package_info_cb callback, void *user_data)
175 {
176         foreach_pkg_context_s foreach_pkg_context = {
177                 .callback = callback,
178                 .user_data = user_data,
179         };
180         int ret = 0;
181
182         if (callback == NULL)
183         {
184                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
185         }
186         uid_t uid = getuid();
187         if (uid != GLOBAL_USER)
188                 ret = pkgmgrinfo_pkginfo_get_usr_list(package_info_foreach_package_info_cb, &foreach_pkg_context, uid);
189         else
190                 ret = pkgmgrinfo_pkginfo_get_list(package_info_foreach_package_info_cb, &foreach_pkg_context);
191         if (ret < 0) {
192                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
193         }
194
195         return PACKAGE_MANAGER_ERROR_NONE;
196 }
197
198 int package_info_filter_foreach_package_info(pkgmgrinfo_pkginfo_filter_h handle, package_manager_package_info_cb callback, void *user_data)
199 {
200         foreach_pkg_context_s foreach_pkg_context = {
201                 .callback = callback,
202                 .user_data = user_data,
203         };
204         int ret;
205         uid_t uid;
206
207         if ((handle == NULL) || (callback == NULL))
208                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
209
210         uid = getuid();
211         if (uid != GLOBAL_USER)
212                 ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context, uid);
213         else
214                 ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context);
215
216         if (ret < 0)
217                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
218
219         return PACKAGE_MANAGER_ERROR_NONE;
220 }
221