2 * Copyright (c) 2014-2018 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <privilege_db_manager.h>
22 #include <cynara-session.h>
23 #include <cynara-client.h>
25 #include <sys/smack.h>
26 #include <system_info.h>
27 #include "privilege_information.h"
30 #define LOG_TAG "PRIVILEGE_INFO"
33 #define PRIVACY_FEATURE "http://tizen.org/feature/security.privacy_privilege"
34 #define CHECK_FEATURE_SUPPORTED(feature_name) \
36 bool is_supported = false; \
37 int ret = system_info_get_platform_bool(feature_name, &is_supported); \
38 if (ret != SYSTEM_INFO_ERROR_NONE) { \
39 LOGE("system_info_get_platform_bool failed. ret = %d", ret); \
40 return PRVINFO_ERROR_INTERNAL_ERROR; \
42 if (!is_supported) { \
43 LOGE("%s is disabled", feature_name); \
44 return PRVINFO_ERROR_NOT_SUPPORTED; \
50 #define TryReturn(condition, expr, returnValue, ...) \
58 #define PI_API __attribute__((visibility("default")))
62 PRVINFO_ERROR_NO_MATCHING_PRIVILEGE = TIZEN_ERROR_PRIVILEGE_INFORMATION | 0x01
63 } privilege_info_internal_error_e;
65 int privilege_info_get_string_id(const char *package_type_string, int display, const char *api_version, const char *privilege, char **string_id)
67 TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
68 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
72 privilege_manager_package_type_e package_type;
74 if (package_type_string != NULL)
75 goto get_string_id_with_package_type;
79 ret = privilege_db_manager_get_privilege_display(PRVMGR_PACKAGE_TYPE_CORE, privilege, api_version, &temp);
81 ret = privilege_db_manager_get_privilege_description(PRVMGR_PACKAGE_TYPE_CORE, privilege, api_version, &temp);
83 if (ret == PRIVILEGE_DB_MANAGER_ERR_NONE)
85 else if (ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT)
86 goto err_internal_error;
90 get_string_id_with_package_type:
91 if (package_type_string == NULL || strcmp(package_type_string, "PRVINFO_PACKAGE_TYPE_WEB") == 0)
92 package_type = PRVMGR_PACKAGE_TYPE_WRT;
93 else if (strcmp(package_type_string, "PRVINFO_PACKAGE_TYPE_NATIVE") == 0)
94 package_type = PRVMGR_PACKAGE_TYPE_CORE;
96 return PRVINFO_ERROR_INVALID_PARAMETER;
99 ret = privilege_db_manager_get_privilege_display(package_type, privilege, api_version, &temp);
101 ret = privilege_db_manager_get_privilege_description(package_type, privilege, api_version, &temp);
104 if (ret == PRIVILEGE_DB_MANAGER_ERR_NONE)
106 else if (ret == PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT)
107 goto err_no_matching_privilege;
109 goto err_internal_error;
112 *string_id = strdup(temp);
113 TryReturn(*string_id != NULL, free(temp), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation is failed.");
115 return PRVINFO_ERROR_NONE;
117 err_no_matching_privilege:
120 return PRVINFO_ERROR_NO_MATCHING_PRIVILEGE;
124 return PRVINFO_ERROR_INTERNAL_ERROR;
127 int privilege_info_get_string_by_string_id(const char *string_id, char **string)
130 TryReturn(string_id != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] string_id is NULL");
132 temp = dgettext("privilege", string_id);
134 *string = strdup(temp);
135 TryReturn(*string != NULL, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] strdup of string failed.");
137 return PRVINFO_ERROR_NONE;
141 int privilege_info_get_display_name(const char *api_version, const char *privilege, char **display_name)
144 char* string_id = NULL;
146 TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
147 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
149 ret = privilege_info_get_string_id(NULL, 1, api_version, privilege, &string_id);
151 if (ret == PRVINFO_ERROR_NO_MATCHING_PRIVILEGE) {
152 char* tempPrivilege = NULL;
157 tempPrivilege = strdup(privilege);
158 TryReturn(tempPrivilege != NULL, free(tempPrivilege), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] tempPrivilege's strdup is failed.");
160 token = strtok_r(tempPrivilege, "/", &save);
163 token = strtok_r(NULL, "/", &save);
165 *display_name = strdup(temp);
166 TryReturn(*display_name != NULL, free(tempPrivilege), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
168 } else if (ret == PRVINFO_ERROR_NONE) {
169 ret = privilege_info_get_string_by_string_id(string_id, display_name);
171 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
173 return PRVINFO_ERROR_INTERNAL_ERROR;
175 return PRVINFO_ERROR_NONE;
180 int privilege_info_get_description(const char *api_version, const char *privilege, char **description)
183 char* string_id = NULL;
185 TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
186 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
188 ret = privilege_info_get_string_id(NULL, 0, api_version, privilege, &string_id);
190 if (ret == PRVINFO_ERROR_NO_MATCHING_PRIVILEGE) {
191 ret = privilege_info_get_string_by_string_id("IDS_TPLATFORM_BODY_THIS_PRIVILEGE_IS_NOT_DEFINED", description);
192 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
193 } else if (ret == PRVINFO_ERROR_NONE) {
194 ret = privilege_info_get_string_by_string_id(string_id, description);
196 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
198 return PRVINFO_ERROR_INTERNAL_ERROR;
200 return PRVINFO_ERROR_NONE;
204 int privilege_info_get_display_name_by_pkgtype(const char *package_type, const char *api_version, const char *privilege, char **display_name)
207 char* string_id = NULL;
209 TryReturn(package_type != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] package_type is NULL");
210 TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
211 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
213 ret = privilege_info_get_string_id(package_type, 1, api_version, privilege, &string_id);
214 TryReturn(ret != PRVINFO_ERROR_INVALID_PARAMETER, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] invalid package_type : %s", package_type);
216 if (ret == PRVINFO_ERROR_NO_MATCHING_PRIVILEGE) {
217 char* tempPrivilege = NULL;
221 tempPrivilege = strdup(privilege);
222 TryReturn(tempPrivilege != NULL, free(tempPrivilege), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] tempPrivilege's strdup is failed.");
223 token = strtok_r(tempPrivilege, "/", &save);
226 token = strtok_r(NULL, "/", &save);
228 *display_name = strdup(temp);
229 TryReturn(*display_name != NULL, free(tempPrivilege), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
231 } else if (ret == PRVINFO_ERROR_NONE) {
232 ret = privilege_info_get_string_by_string_id(string_id, display_name);
234 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
236 return PRVINFO_ERROR_INTERNAL_ERROR;
238 return PRVINFO_ERROR_NONE;
242 int privilege_info_get_description_by_pkgtype(const char *package_type, const char *api_version, const char *privilege, char **description)
245 char* string_id = NULL;
247 TryReturn(package_type != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] package_type is NULL");
248 TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
249 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
251 ret = privilege_info_get_string_id(package_type, 0, api_version, privilege, &string_id);
252 TryReturn(ret != PRVINFO_ERROR_INVALID_PARAMETER, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] invalid package_type : %s", package_type);
254 if (ret == PRVINFO_ERROR_NO_MATCHING_PRIVILEGE) {
255 ret = privilege_info_get_string_by_string_id("IDS_TPLATFORM_BODY_THIS_PRIVILEGE_IS_NOT_DEFINED", description);
256 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
257 } else if (ret == PRVINFO_ERROR_NONE) {
258 ret = privilege_info_get_string_by_string_id(string_id, description);
260 TryReturn(ret == PRVINFO_ERROR_NONE, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
262 return PRVINFO_ERROR_INTERNAL_ERROR;
264 return PRVINFO_ERROR_NONE;
268 int privilege_info_get_privacy_display_name(const char *privilege, char **privacy_display_name)
270 CHECK_FEATURE_SUPPORTED(PRIVACY_FEATURE);
271 TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
272 TryReturn(privilege_db_manager_is('p', privilege) == 1, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege does not exist or is not a privacy related");
274 char* privacy_id = NULL;
275 char* privacy_display_string_id = NULL;
277 TryReturn(privilege_db_manager_get_privacy_by_privilege(privilege, &privacy_id) == PRIVILEGE_DB_MANAGER_ERR_NONE && privacy_id != NULL, , PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] privilege_db_manager_get_privacy_by_privilege failed");
279 TryReturn(privilege_db_manager_get_privacy_display(privacy_id, &privacy_display_string_id) == PRIVILEGE_DB_MANAGER_ERR_NONE && privacy_display_string_id != NULL, free(privacy_id), PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] privilege_db_manager_get_privacy_display failed");
281 TryReturn(privilege_info_get_string_by_string_id(privacy_display_string_id, privacy_display_name) == PRVINFO_ERROR_NONE && *privacy_display_name != NULL, free(privacy_id); free(privacy_display_string_id), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
284 free(privacy_display_string_id);
285 return PRVINFO_ERROR_NONE;
289 int privilege_info_get_privacy_privilege_status(const char *privilege, bool *status)
291 CHECK_FEATURE_SUPPORTED(PRIVACY_FEATURE);
292 TryReturn(privilege != NULL, *status = true, PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
293 TryReturn(privilege_db_manager_is('p', privilege) == 1, *status = true, PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege does not exist or is not a privacy related");
295 char* smack_label = NULL;
296 TryReturn(smack_new_label_from_self(&smack_label) != -1, *status = true, PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] smack_new_label_from_self() failed.");
298 cynara *cynara = NULL;
299 TryReturn(cynara_initialize(&cynara, NULL) == CYNARA_API_SUCCESS, *status = true; cynara = NULL; free(smack_label), PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] cynara_initialize() failed.");
301 char *session = NULL;
302 session = cynara_session_from_pid(getpid());
303 TryReturn(session != NULL, *status = true; cynara_finish(cynara); free(smack_label), PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] cynara_session_from_pid() failed");
306 int result = snprintf(uid, UIDMAXLEN, "%d", getuid());
307 TryReturn(uid != NULL && result > 0, *status = true; free(session); cynara_finish(cynara); free(smack_label), PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] snprintf() for uid failed.");
309 result = cynara_simple_check(cynara, smack_label, session, uid, privilege);
310 int ret = PRVINFO_ERROR_NONE;
312 cynara_finish(cynara);
314 LOGD("result of cynara_check(cynara %s, session, %s, %s) result = %d", smack_label, uid, privilege, result);
316 if (result == CYNARA_API_ACCESS_DENIED) {
318 } else if (result == CYNARA_API_ACCESS_ALLOWED) {
322 LOGE("[PRVINFO_ERROR_INTERNAL_ERROR] cynara_check() failed. ret = %d", result);
323 ret = PRVINFO_ERROR_INTERNAL_ERROR;