4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <sys/smack.h>
25 #include "calendar_db.h"
26 #include "cal_internal.h"
27 #include "cal_typedef.h"
30 #include "cal_record.h"
31 #include "cal_mutex.h"
32 #include "cal_db_util.h"
34 #include "cal_access_control.h"
35 #include "cal_server_service.h"
36 #include "cal_utils.h"
39 unsigned int thread_id;
44 } cal_permission_info_s;
47 CAL_SMACK_NOT_CHECKED,
48 CAL_SMACK_ENABLED, /* 1 */
49 CAL_SMACK_DISABLED, /* 0 */
52 static GList *__thread_list = NULL;
53 static int have_smack = CAL_SMACK_NOT_CHECKED;
55 static cal_permission_info_s* _cal_access_control_find_permission_info(unsigned int thread_id)
59 for (cursor = __thread_list; cursor; cursor = cursor->next) {
60 cal_permission_info_s *info = NULL;
62 if (info->thread_id == thread_id)
68 /* check SMACK enable or disable */
69 static int _cal_have_smack(void)
71 if (CAL_SMACK_NOT_CHECKED == have_smack) {
72 if (NULL == smack_smackfs_path())
73 have_smack = CAL_SMACK_DISABLED;
75 have_smack = CAL_SMACK_ENABLED;
80 static void _cal_access_control_set_permission_info(cal_permission_info_s *info)
83 bool smack_enabled = false;
85 if (CAL_SMACK_ENABLED == _cal_have_smack())
88 INFO("SAMCK disabled");
90 /* white listing : core module */
91 free(info->write_list);
92 info->write_list = NULL;
93 info->write_list_count = 0;
95 char query[CAL_DB_SQL_MAX_LEN] = {0};
97 snprintf(query, sizeof(query), "SELECT count(id) FROM %s WHERE deleted = 0 ", CAL_TABLE_CALENDAR);
98 ret = cal_db_util_query_get_first_int_result(query, NULL, &count);
99 if (CALENDAR_ERROR_NONE != ret) {
100 /* LCOV_EXCL_START */
101 ERR("cal_db_util_query_get_first_int_result() Fail(%d)", ret);
102 SECURE("query[%s]", query);
107 info->write_list = calloc(count +1, sizeof(int));
108 if (NULL == info->write_list) {
109 /* LCOV_EXCL_START */
110 ERR("calloc() Fail");
114 info->write_list_count = 0;
116 sqlite3_stmt *stmt = NULL;
117 snprintf(query, sizeof(query), "SELECT id, mode, owner_label FROM %s WHERE deleted = 0 ", CAL_TABLE_CALENDAR);
118 ret = cal_db_util_query_prepare(query, &stmt);
119 if (CALENDAR_ERROR_NONE != ret) {
120 /* LCOV_EXCL_START */
121 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
122 SECURE("query[%s]", query);
128 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
133 id = sqlite3_column_int(stmt, 0);
134 mode = sqlite3_column_int(stmt, 1);
135 temp = (char *)sqlite3_column_text(stmt, 2);
137 if (!smack_enabled) /* smack disabled */
138 info->write_list[write_index++] = id;
139 else if (NULL == info->ipc) /* calendar-service daemon */
140 info->write_list[write_index++] = id;
141 else if (info->smack_label && temp && 0 == strcmp(temp, info->smack_label)) /* owner */
142 info->write_list[write_index++] = id;
143 else if (CALENDAR_BOOK_MODE_NONE == mode)
144 info->write_list[write_index++] = id;
146 info->write_list_count = write_index;
147 sqlite3_finalize(stmt);
150 void cal_access_control_set_client_info(void *ipc, const char *smack_label)
152 unsigned int thread_id = (unsigned int)pthread_self();
153 cal_permission_info_s *info = NULL;
155 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
156 info = _cal_access_control_find_permission_info(thread_id);
158 info = calloc(1, sizeof(cal_permission_info_s));
160 /* LCOV_EXCL_START */
161 ERR("calloc() Fail");
162 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
166 __thread_list = g_list_append(__thread_list, info);
168 info->thread_id = thread_id;
171 free(info->smack_label);
172 info->smack_label = cal_strdup(smack_label);
173 _cal_access_control_set_permission_info(info);
175 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
178 void cal_access_control_unset_client_info(void)
180 cal_permission_info_s *find = NULL;
182 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
183 find = _cal_access_control_find_permission_info(pthread_self());
185 CAL_FREE(find->smack_label);
186 CAL_FREE(find->write_list);
187 __thread_list = g_list_remove(__thread_list, find);
190 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
193 char* cal_access_control_get_label(void)
195 unsigned int thread_id = (unsigned int)pthread_self();
196 cal_permission_info_s *info = NULL;
198 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
199 info = _cal_access_control_find_permission_info(thread_id);
201 char *smack_label = NULL;
202 if (info && info->smack_label)
203 smack_label = strdup(info->smack_label);
205 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
209 void cal_access_control_reset(void)
211 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
213 for (cursor = __thread_list; cursor; cursor = cursor->next) {
214 cal_permission_info_s *info = NULL;
217 _cal_access_control_set_permission_info(info);
219 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
222 bool cal_access_control_have_write_permission(int book_id)
224 cal_permission_info_s *info = NULL;
226 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
227 unsigned int thread_id = pthread_self();
228 info = _cal_access_control_find_permission_info(thread_id);
230 /* LCOV_EXCL_START */
231 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
232 ERR("_cal_access_control_find_permission_info() Fail");
237 if (NULL == info->write_list) {
238 /* LCOV_EXCL_START */
239 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
240 ERR("there is no write access info");
246 for (i = 0; i < info->write_list_count; i++) {
247 if (book_id == info->write_list[i]) {
248 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
253 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
254 ERR("thread(0x%x), No write permission of book_id(%d)", thread_id, book_id);
258 int cal_is_owner(int book_id)
261 sqlite3_stmt *stmt = NULL;
262 char query[CAL_DB_SQL_MAX_LEN] = {0};
263 char *owner_label = NULL;
264 char *saved_smack = NULL;
266 snprintf(query, sizeof(query), "SELECT owner_label FROM %s WHERE id = %d",
267 CAL_TABLE_CALENDAR, book_id);
268 ret = cal_db_util_query_prepare(query, &stmt);
269 if (CALENDAR_ERROR_NONE != ret) {
270 /* LCOV_EXCL_START */
271 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
272 SECURE("query[%s]", query);
277 if (CAL_SQLITE_ROW != cal_db_util_stmt_step(stmt)) {
278 /* LCOV_EXCL_START */
279 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
280 sqlite3_finalize(stmt);
281 return CALENDAR_ERROR_DB_FAILED;
285 ret = CALENDAR_ERROR_PERMISSION_DENIED;
287 owner_label = (char*)sqlite3_column_text(stmt, 0);
288 saved_smack = cal_access_control_get_label();
290 if (owner_label && saved_smack && CAL_STRING_EQUAL == strcmp(owner_label, saved_smack))
291 ret = CALENDAR_ERROR_NONE;
293 sqlite3_finalize(stmt);