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