Release version 0.11.2
[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 <stdio.h>
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include <sys/syscall.h>
21 #include <unistd.h>
22 #include <pthread.h>
23
24 #include <package-manager.h>
25 #include <pkgmgr-info.h>
26 #include <tzplatform_config.h>
27 #include <cynara-client.h>
28 #include <cynara-session.h>
29
30 #include "package_info.h"
31 #include "package_manager.h"
32 #include "package_manager_internal.h"
33
34 #define MAX_SMACK_LABEL_LEN 255
35 #define gettid() syscall(SYS_gettid)
36
37 typedef struct _foreach_pkg_context_ {
38         package_manager_package_info_cb callback;
39         void *user_data;
40 } foreach_pkg_context_s;
41
42 static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
43
44 int check_privilege(privilege_type type)
45 {
46         cynara *p_cynara;
47         int fd;
48         int ret;
49         char subject_label[MAX_SMACK_LABEL_LEN + 1] = { 0 };
50         char uid[10];
51         char *session;
52         const char *privilege;
53         pid_t pid = getpid();
54         pid_t tid = gettid();
55
56         if (pid == tid) {
57                 fd = open("/proc/self/attr/current", O_RDONLY);
58         } else {
59                 /* LCOV_EXCL_START */
60                 // Check current thread smack label.
61                 char path[256] = { 0 };
62                 pid = tid;
63                 snprintf(path, sizeof(path), "/proc/%d/attr/current", tid);
64                 fd = open(path, O_RDONLY);
65                 /* LCOV_EXCL_STOP */
66         }
67         if (fd < 0) {
68                 /* LCOV_EXCL_START */
69                 LOGE("open failed: %d", errno);
70                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
71                 /* LCOV_EXCL_STOP */
72         }
73
74         ret = read(fd, subject_label, MAX_SMACK_LABEL_LEN);
75         if (ret < 0) {
76                 /* LCOV_EXCL_START */
77                 LOGE("read failed: %d", errno);
78                 close(fd);
79                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
80                 /* LCOV_EXCL_STOP */
81         }
82         close(fd);
83
84         pthread_mutex_lock(&__mutex);
85         ret = cynara_initialize(&p_cynara, NULL);
86         if (ret != CYNARA_API_SUCCESS) {
87                 /* LCOV_EXCL_START */
88                 LOGE("init cynara failed: %d", ret);
89                 pthread_mutex_unlock(&__mutex);
90                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
91                 /* LCOV_EXCL_STOP */
92         }
93
94         snprintf(uid, 10, "%d", getuid());
95         session = cynara_session_from_pid(pid);
96
97         switch (type) {
98         case PRIVILEGE_PACKAGE_MANAGER_INFO:
99                 privilege = "http://tizen.org/privilege/packagemanager.info";
100                 break;
101         /* LCOV_EXCL_START */
102         case PRIVILEGE_PACKAGE_MANAGER_ADMIN:
103                 privilege = "http://tizen.org/privilege/packagemanager.admin";
104                 break;
105         /* LCOV_EXCL_STOP */
106         case PRIVILEGE_PACKAGE_MANAGER_CACHE:
107                 privilege =
108                         "http://tizen.org/privilege/packagemanager.clearcache";
109                 break;
110         /* LCOV_EXCL_START */
111         default:
112                 privilege = NULL;
113                 break;
114         /* LCOV_EXCL_STOP */
115         }
116
117         ret = cynara_check(p_cynara, subject_label, session, uid, privilege);
118
119         free(session);
120         cynara_finish(p_cynara);
121         pthread_mutex_unlock(&__mutex);
122
123         if (ret != CYNARA_API_ACCESS_ALLOWED) {
124                 /* LCOV_EXCL_START */
125                 LOGE("cynara access check failed: %d", ret);
126                 return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
127                 /* LCOV_EXCL_STOP */
128         }
129
130         return PACKAGE_MANAGER_ERROR_NONE;
131 }
132
133 static const char *package_manager_error_to_string(package_manager_error_e
134                                                    error)
135 {
136         switch (error) {
137         case PACKAGE_MANAGER_ERROR_NONE:
138                 return "NONE";
139         case PACKAGE_MANAGER_ERROR_INVALID_PARAMETER:
140                 return "INVALID_PARAMETER";
141         /* LCOV_EXCL_START */
142         case PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY:
143                 return "OUT_OF_MEMORY";
144         /* LCOV_EXCL_STOP */
145         case PACKAGE_MANAGER_ERROR_IO_ERROR:
146                 return "IO_ERROR";
147         case PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE:
148                 return "NO_SUCH_PACKAGE";
149         /* LCOV_EXCL_START */
150         case PACKAGE_MANAGER_ERROR_PERMISSION_DENIED:
151                 return "PERMISSION_DENIED";
152         case PACKAGE_MANAGER_ERROR_SYSTEM_ERROR:
153                 return "SEVERE_SYSTEM_ERROR";
154         default:
155                 return "UNKNOWN";
156         /* LCOV_EXCL_STOP */
157         }
158 }
159
160 int package_manager_convert_internal_error(int internal_error)
161 {
162         switch (internal_error) {
163         case PKGMGR_R_ERROR:
164         case PKGMGR_R_ECOMM:
165         case PKGMGR_R_ESYSTEM:
166                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
167         case PKGMGR_R_EINVAL:
168                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
169         case PKGMGR_R_ETIMEOUT:
170         case PKGMGR_R_EPRIV:
171                 return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
172         case PKGMGR_R_ENOPKG:
173                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
174         case PKGMGR_R_ENOMEM:
175                 return PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY;
176         case PKGMGR_R_EIO:
177                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
178         /* LCOV_EXCL_START */
179         default:
180                 _LOGE("Unexpected error");
181                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
182         /* LCOV_EXCL_STOP */
183         }
184 }
185
186 int package_manager_error(package_manager_error_e error,
187                                  const char *function, const char *description)
188 {
189         if (description) {
190                 /* LCOV_EXCL_START */
191                 _LOGE("[%s] %s(0x%08x) : %s", function,
192                      package_manager_error_to_string(error), error,
193                      description);
194                 /* LCOV_EXCL_STOP */
195         } else {
196                 _LOGE("[%s] %s(0x%08x)", function,
197                      package_manager_error_to_string(error), error);
198         }
199
200         return error;
201 }
202
203 int package_info_get_package_info(const char *package, package_info_h *package_info)
204 {
205         return package_info_create(package, package_info);
206 }
207
208 static int package_info_foreach_package_info_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
209 {
210         foreach_pkg_context_s *foreach_pkg_context = user_data;
211         package_info_h package_info = NULL;
212         bool r = false;
213         int ret;
214
215         if (handle == NULL || foreach_pkg_context == NULL) {
216                 /* LCOV_EXCL_START */
217                 package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
218                 return PMINFO_R_EINVAL;
219                 /* LCOV_EXCL_STOP */
220         }
221
222         ret = package_info_create_with_pkginfo(handle, &package_info);
223         if (ret != PACKAGE_MANAGER_ERROR_NONE)
224                 /* LCOV_EXCL_START */
225                 return package_manager_error(ret, __FUNCTION__, NULL);
226                 /* LCOV_EXCL_STOP */
227
228         r = foreach_pkg_context->callback(package_info, foreach_pkg_context->user_data);
229
230         package_info_destroy_handle(package_info);
231
232         return (r == true) ? PMINFO_R_OK : PMINFO_R_ERROR;
233 }
234
235 int package_info_foreach_package_info(package_manager_package_info_cb callback, void *user_data)
236 {
237         foreach_pkg_context_s foreach_pkg_context = {
238                 .callback = callback,
239                 .user_data = user_data,
240         };
241         int ret = 0;
242
243         if (callback == NULL)
244                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
245
246         ret = pkgmgrinfo_pkginfo_get_list(package_info_foreach_package_info_cb, &foreach_pkg_context);
247
248         if (ret < 0)
249                 /* LCOV_EXCL_START */
250                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
251                 /* LCOV_EXCL_STOP */
252
253         return PACKAGE_MANAGER_ERROR_NONE;
254 }
255
256 int package_info_filter_foreach_package_info(pkgmgrinfo_pkginfo_filter_h handle, package_manager_package_info_cb callback, void *user_data)
257 {
258         foreach_pkg_context_s foreach_pkg_context = {
259                 .callback = callback,
260                 .user_data = user_data,
261         };
262         int ret;
263
264         if ((handle == NULL) || (callback == NULL))
265                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
266
267         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context);
268
269         if (ret < 0)
270                 /* LCOV_EXCL_START */
271                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
272                 /* LCOV_EXCL_STOP */
273
274         return PACKAGE_MANAGER_ERROR_NONE;
275 }