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 ERR("cal_db_util_query_get_first_int_result() Fail(%d)", ret);
101 SECURE("query[%s]", query);
105 info->write_list = calloc(count +1, sizeof(int));
106 if (NULL == info->write_list) {
107 ERR("calloc() Fail");
110 info->write_list_count = 0;
112 sqlite3_stmt *stmt = NULL;
113 snprintf(query, sizeof(query), "SELECT id, mode, owner_label FROM %s WHERE deleted = 0 ", CAL_TABLE_CALENDAR);
114 ret = cal_db_util_query_prepare(query, &stmt);
115 if (CALENDAR_ERROR_NONE != ret) {
116 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
117 SECURE("query[%s]", query);
122 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
127 id = sqlite3_column_int(stmt, 0);
128 mode = sqlite3_column_int(stmt, 1);
129 temp = (char *)sqlite3_column_text(stmt, 2);
131 if (!smack_enabled) /* smack disabled */
132 info->write_list[write_index++] = id;
133 else if (NULL == info->ipc) /* calendar-service daemon */
134 info->write_list[write_index++] = id;
135 else if (info->smack_label && temp && 0 == strcmp(temp, info->smack_label)) /* owner */
136 info->write_list[write_index++] = id;
137 else if (CALENDAR_BOOK_MODE_NONE == mode)
138 info->write_list[write_index++] = id;
140 info->write_list_count = write_index;
141 sqlite3_finalize(stmt);
144 void cal_access_control_set_client_info(void *ipc, const char *smack_label)
146 unsigned int thread_id = (unsigned int)pthread_self();
147 cal_permission_info_s *info = NULL;
149 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
150 info = _cal_access_control_find_permission_info(thread_id);
152 info = calloc(1, sizeof(cal_permission_info_s));
154 ERR("calloc() Fail");
155 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
158 __thread_list = g_list_append(__thread_list, info);
160 info->thread_id = thread_id;
163 free(info->smack_label);
164 info->smack_label = cal_strdup(smack_label);
165 _cal_access_control_set_permission_info(info);
167 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
170 void cal_access_control_unset_client_info(void)
172 cal_permission_info_s *find = NULL;
174 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
175 find = _cal_access_control_find_permission_info(pthread_self());
177 CAL_FREE(find->smack_label);
178 CAL_FREE(find->write_list);
179 __thread_list = g_list_remove(__thread_list, find);
182 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
185 char* cal_access_control_get_label(void)
187 unsigned int thread_id = (unsigned int)pthread_self();
188 cal_permission_info_s *info = NULL;
190 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
191 info = _cal_access_control_find_permission_info(thread_id);
193 char *smack_label = NULL;
194 if (info && info->smack_label)
195 smack_label = strdup(info->smack_label);
197 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
201 void cal_access_control_reset(void)
203 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
205 for (cursor = __thread_list; cursor; cursor = cursor->next) {
206 cal_permission_info_s *info = NULL;
209 _cal_access_control_set_permission_info(info);
211 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
214 bool cal_access_control_have_write_permission(int book_id)
216 cal_permission_info_s *info = NULL;
218 cal_mutex_lock(CAL_MUTEX_ACCESS_CONTROL);
219 unsigned int thread_id = pthread_self();
220 info = _cal_access_control_find_permission_info(thread_id);
222 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
223 ERR("_cal_access_control_find_permission_info() Fail");
227 if (NULL == info->write_list) {
228 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
229 ERR("there is no write access info");
234 for (i = 0; i < info->write_list_count; i++) {
235 if (book_id == info->write_list[i]) {
236 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
241 cal_mutex_unlock(CAL_MUTEX_ACCESS_CONTROL);
242 ERR("thread(0x%x), No write permission of book_id(%d)", thread_id, book_id);
246 int cal_is_owner(int book_id)
249 sqlite3_stmt *stmt = NULL;
250 char query[CAL_DB_SQL_MAX_LEN] = {0};
251 char *owner_label = NULL;
252 char *saved_smack = NULL;
254 snprintf(query, sizeof(query), "SELECT owner_label FROM %s WHERE id = %d",
255 CAL_TABLE_CALENDAR, book_id);
256 ret = cal_db_util_query_prepare(query, &stmt);
257 if (CALENDAR_ERROR_NONE != ret) {
258 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
259 SECURE("query[%s]", query);
263 if (CAL_SQLITE_ROW != cal_db_util_stmt_step(stmt)) {
264 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
265 sqlite3_finalize(stmt);
266 return CALENDAR_ERROR_DB_FAILED;
269 ret = CALENDAR_ERROR_PERMISSION_DENIED;
271 owner_label = (char*)sqlite3_column_text(stmt, 0);
272 saved_smack = cal_access_control_get_label();
274 if (owner_label && saved_smack && CAL_STRING_EQUAL == strcmp(owner_label, saved_smack))
275 ret = CALENDAR_ERROR_NONE;
277 sqlite3_finalize(stmt);