ee0ccf96dfc3d742354236296e21e05dbf7a0cef
[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         unsigned long pid = getpid();
54         unsigned long tid = gettid();
55
56         if (pid == tid) {
57                 fd = open("/proc/self/attr/current", O_RDONLY);
58         } else {
59                 // Check current thread smack label.
60                 char path[256] = { 0 };
61                 pid = tid;
62                 snprintf(path, sizeof(path), "/proc/%lu/attr/current", tid);
63                 fd = open(path, O_RDONLY);
64         }
65         if (fd < 0) {
66                 LOGE("open failed: %d", errno);
67                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
68         }
69
70         ret = read(fd, subject_label, MAX_SMACK_LABEL_LEN);
71         if (ret < 0) {
72                 LOGE("read failed: %d", errno);
73                 close(fd);
74                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
75         }
76         close(fd);
77
78         pthread_mutex_lock(&__mutex);
79         ret = cynara_initialize(&p_cynara, NULL);
80         if (ret != CYNARA_API_SUCCESS) {
81                 LOGE("init cynara failed: %d", ret);
82                 pthread_mutex_unlock(&__mutex);
83                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
84         }
85
86         snprintf(uid, 10, "%d", getuid());
87         session = cynara_session_from_pid(pid);
88
89         switch (type) {
90         case PRIVILEGE_PACKAGE_MANAGER_INFO:
91                 privilege = "http://tizen.org/privilege/packagemanager.info";
92                 break;
93         case PRIVILEGE_PACKAGE_MANAGER_ADMIN:
94                 privilege = "http://tizen.org/privilege/packagemanager.admin";
95                 break;
96         case PRIVILEGE_PACKAGE_MANAGER_CACHE:
97                 privilege =
98                         "http://tizen.org/privilege/packagemanager.clearcache";
99                 break;
100         default:
101                 privilege = NULL;
102                 break;
103         }
104
105         ret = cynara_check(p_cynara, subject_label, session, uid, privilege);
106
107         free(session);
108         cynara_finish(p_cynara);
109         pthread_mutex_unlock(&__mutex);
110
111         if (ret != CYNARA_API_ACCESS_ALLOWED) {
112                 LOGE("cynara access check failed: %d", ret);
113                 return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
114         }
115
116         return PACKAGE_MANAGER_ERROR_NONE;
117 }
118
119 static const char *package_manager_error_to_string(package_manager_error_e
120                                                    error)
121 {
122         switch (error) {
123         case PACKAGE_MANAGER_ERROR_NONE:
124                 return "NONE";
125         case PACKAGE_MANAGER_ERROR_INVALID_PARAMETER:
126                 return "INVALID_PARAMETER";
127         case PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY:
128                 return "OUT_OF_MEMORY";
129         case PACKAGE_MANAGER_ERROR_IO_ERROR:
130                 return "IO_ERROR";
131         case PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE:
132                 return "NO_SUCH_PACKAGE";
133         case PACKAGE_MANAGER_ERROR_PERMISSION_DENIED:
134                 return "PERMISSION_DENIED";
135         case PACKAGE_MANAGER_ERROR_SYSTEM_ERROR:
136                 return "SEVERE_SYSTEM_ERROR";
137         default:
138                 return "UNKNOWN";
139         }
140 }
141
142 int package_manager_convert_internal_error(int internal_error)
143 {
144         switch (internal_error) {
145         case PKGMGR_R_ERROR:
146         case PKGMGR_R_ECOMM:
147         case PKGMGR_R_ESYSTEM:
148                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
149         case PKGMGR_R_EINVAL:
150                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
151         case PKGMGR_R_ETIMEOUT:
152         case PKGMGR_R_EPRIV:
153                 return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
154         case PKGMGR_R_ENOPKG:
155                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
156         case PKGMGR_R_ENOMEM:
157                 return PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY;
158         case PKGMGR_R_EIO:
159                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
160         default:
161                 _LOGE("Unexpected error");
162                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
163         }
164 }
165
166 int package_manager_error(package_manager_error_e error,
167                                  const char *function, const char *description)
168 {
169         if (description) {
170                 _LOGE("[%s] %s(0x%08x) : %s", function,
171                      package_manager_error_to_string(error), error,
172                      description);
173         } else {
174                 _LOGE("[%s] %s(0x%08x)", function,
175                      package_manager_error_to_string(error), error);
176         }
177
178         return error;
179 }
180
181 int package_info_get_package_info(const char *package, package_info_h *package_info)
182 {
183         return package_info_create(package, package_info);
184 }
185
186 static int package_info_foreach_package_info_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
187 {
188         foreach_pkg_context_s *foreach_pkg_context = user_data;
189         package_info_h package_info = NULL;
190         bool r = false;
191         int ret;
192
193         if (handle == NULL || foreach_pkg_context == NULL) {
194                 package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
195                 return PMINFO_R_EINVAL;
196         }
197
198         ret = package_info_create_with_pkginfo(handle, &package_info);
199         if (ret != PACKAGE_MANAGER_ERROR_NONE)
200                 return package_manager_error(ret, __FUNCTION__, NULL);
201
202         r = foreach_pkg_context->callback(package_info, foreach_pkg_context->user_data);
203
204         package_info_destroy_handle(package_info);
205
206         return (r == true) ? PMINFO_R_OK : PMINFO_R_ERROR;
207 }
208
209 int package_info_foreach_package_info(package_manager_package_info_cb callback, void *user_data)
210 {
211         foreach_pkg_context_s foreach_pkg_context = {
212                 .callback = callback,
213                 .user_data = user_data,
214         };
215         int ret = 0;
216
217         if (callback == NULL)
218                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
219
220         ret = pkgmgrinfo_pkginfo_get_list(package_info_foreach_package_info_cb, &foreach_pkg_context);
221
222         if (ret < 0)
223                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
224
225         return PACKAGE_MANAGER_ERROR_NONE;
226 }
227
228 int package_info_filter_foreach_package_info(pkgmgrinfo_pkginfo_filter_h handle, package_manager_package_info_cb callback, void *user_data)
229 {
230         foreach_pkg_context_s foreach_pkg_context = {
231                 .callback = callback,
232                 .user_data = user_data,
233         };
234         int ret;
235
236         if ((handle == NULL) || (callback == NULL))
237                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
238
239         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context);
240
241         if (ret < 0)
242                 return PACKAGE_MANAGER_ERROR_IO_ERROR;
243
244         return PACKAGE_MANAGER_ERROR_NONE;
245 }