4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
32 #include <sys/smack.h>
34 #include <tzplatform_config.h>
35 #include "ail_private.h"
38 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
40 #define QUERY_ATTACH "attach database '%s' as Global"
41 #define QUERY_CREATE_VIEW_APP "CREATE temp VIEW app_info as select distinct * from (select * from main.app_info m union select * from Global.app_info g)"
43 #define QUERY_CREATE_VIEW_LOCAL "CREATE temp VIEW localname as select distinct * from (select * from main.localname m union select * from Global.localname g)"
45 #define SET_SMACK_LABEL(x,uid) \
46 if(smack_setlabel((x), (((uid) == GLOBAL_USER)?"*":"User"), SMACK_LABEL_ACCESS)) _E("failed chsmack -a \"User/*\" %s", x); \
47 else _D("chsmack -a \"User/*\" %s", x);
50 #define retv_with_dbmsg_if(expr, val) do { \
52 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
53 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
54 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
55 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
56 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
57 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
58 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
59 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
64 static __thread struct {
75 static __thread sqlite3 *dbInit = NULL;
77 static int ail_db_change_perm(const char *db_file, uid_t uid)
80 char journal_file[BUFSIZE];
83 struct passwd *userinfo = NULL;
84 files[0] = (char *)db_file;
85 files[1] = journal_file;
88 retv_if(!db_file, AIL_ERROR_FAIL);
89 if(getuid() != OWNER_ROOT) //At this time we should be root to apply this
91 userinfo = getpwuid(uid);
93 _E("FAIL: user %d doesn't exist", uid);
94 return AIL_ERROR_FAIL;
96 snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
98 for (i = 0; files[i]; i++) {
99 // Compare git_t type and not group name
100 ret = chown(files[i], uid, userinfo->pw_gid);
101 SET_SMACK_LABEL(files[i],uid)
103 strerror_r(errno, buf, sizeof(buf));
104 _E("FAIL : chown %s %d.%d, because %s", db_file, uid, userinfo->pw_gid, buf);
105 return AIL_ERROR_FAIL;
108 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
110 strerror_r(errno, buf, sizeof(buf));
111 _E("FAIL : chmod %s 0664, because %s", db_file, buf);
112 return AIL_ERROR_FAIL;
119 char* ail_get_icon_path(uid_t uid)
122 struct group *grpinfo = NULL;
124 struct passwd *userinfo = getpwuid(uid);
127 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
130 if (uid != GLOBAL_USER) {
131 if (userinfo == NULL) {
132 _E("getpwuid(%d) returns NULL !", uid);
135 grpinfo = getgrnam("users");
136 if (grpinfo == NULL) {
137 _E("getgrnam(users) returns NULL !");
140 // Compare git_t type and not group name
141 if (grpinfo->gr_gid != userinfo->pw_gid) {
142 _E("UID [%d] does not belong to 'users' group!", uid);
145 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
147 result = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
149 int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
150 if (ret == -1 && errno != EEXIST) {
151 _E("FAIL : to create directory %s %d", result, errno);
152 } else if (getuid() == OWNER_ROOT) {
153 ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
154 SET_SMACK_LABEL(result,uid)
157 strerror_r(errno, buf, sizeof(buf));
158 _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
164 char* ail_get_app_DB_journal(uid_t uid)
167 char *app_path = ail_get_app_DB(uid);
170 asprintf(&result, "%s-journal", app_path);
174 char* ail_get_app_DB(uid_t uid)
177 struct group *grpinfo = NULL;
179 struct passwd *userinfo = getpwuid(uid);
182 _E("FAIL : Root is not allowed! switch to DEFAULT_USER");
185 if (uid != GLOBAL_USER) {
186 if (userinfo == NULL) {
187 _E("getpwuid(%d) returns NULL !", uid);
190 grpinfo = getgrnam("users");
191 if (grpinfo == NULL) {
192 _E("getgrnam(users) returns NULL !");
195 // Compare git_t type and not group name
196 if (grpinfo->gr_gid != userinfo->pw_gid) {
197 _E("UID [%d] does not belong to 'users' group!", uid);
200 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
202 result = strdup(APP_INFO_DB_FILE);
204 char *temp = strdup(result);
205 dir = strrchr(temp, '/');
212 int ret = mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
213 if (ret == -1 && errno != EEXIST) {
214 _E("FAIL : to create directory %s %d", temp, errno);
215 } else if (getuid() == OWNER_ROOT) {
216 ret = chown(temp, uid, ((grpinfo)?grpinfo->gr_gid:0));
217 SET_SMACK_LABEL(temp,uid)
220 strerror_r(errno, buf, sizeof(buf));
221 _E("FAIL : chown %s %d.%d, because %s", temp, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
228 char* ail_get_desktop_path(uid_t uid)
231 struct group *grpinfo = NULL;
233 struct passwd *userinfo = getpwuid(uid);
236 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
239 if (uid != GLOBAL_USER) {
240 if (userinfo == NULL) {
241 _E("getpwuid(%d) returns NULL !", uid);
244 grpinfo = getgrnam("users");
245 if (grpinfo == NULL) {
246 _E("getgrnam(users) returns NULL !");
249 // Compare git_t type and not group name
250 if (grpinfo->gr_gid != userinfo->pw_gid) {
251 _E("UID [%d] does not belong to 'users' group!", uid);
254 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
256 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
258 int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
259 if (ret == -1 && errno != EEXIST) {
260 _E("FAIL : to create directory %s %d", result, errno);
261 } else if (getuid() == OWNER_ROOT) {
262 ret = chown(result, uid, ((grpinfo)?grpinfo->gr_gid:0));
263 SET_SMACK_LABEL(result,uid)
266 strerror_r(errno, buf, sizeof(buf));
267 _E("FAIL : chown %s %d.%d, because %s", result, uid, ((grpinfo)?grpinfo->gr_gid:0), buf);
274 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
278 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
279 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
280 retv_if(!db, AIL_ERROR_DB_FAILED);
282 ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
283 if (ret != SQLITE_OK) {
284 _E("%s\n", sqlite3_errmsg(db));
285 return AIL_ERROR_DB_FAILED;
290 ail_error_e db_open(db_open_mode mode, uid_t uid)
295 const char *tbls[3] = {
296 "CREATE TABLE app_info "
297 "(package TEXT PRIMARY KEY, "
298 "exec TEXT DEFAULT 'No Exec', "
299 "name TEXT DEFAULT 'No Name', "
300 "type TEXT DEFAULT 'Application', "
301 "icon TEXT DEFAULT 'No Icon', "
305 "x_slp_service TEXT, "
306 "x_slp_packagetype TEXT, "
307 "x_slp_packagecategories TEXT, "
308 "x_slp_packageid TEXT, "
311 "x_slp_exe_path TEXT, "
314 "x_slp_domain TEXT, "
315 "x_slp_submodemainid TEXT, "
316 "x_slp_installedstorage TEXT, "
317 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
318 "x_slp_installedtime INTEGER DEFAULT 0, "
319 "nodisplay INTEGER DEFAULT 0, "
320 "x_slp_taskmanage INTEGER DEFAULT 1, "
321 "x_slp_multiple INTEGER DEFAULT 0, "
322 "x_slp_removable INTEGER DEFAULT 1, "
323 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
324 "x_slp_enabled INTEGER DEFAULT 1, "
325 "x_slp_submode INTEGER DEFAULT 0, "
326 "desktop TEXT UNIQUE NOT NULL);",
327 "CREATE TABLE localname (package TEXT NOT NULL, "
328 "locale TEXT NOT NULL, "
329 "name TEXT NOT NULL, "
330 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
335 char *db = ail_get_app_DB(uid);
336 char *global_db = ail_get_app_DB(GLOBAL_USER);
338 if (access(db, F_OK)) {
339 if (AIL_ERROR_OK == db_util_open_with_options(db, &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
341 for (i = 0; tbls[i] != NULL; i++) {
342 ret = do_db_exec(tbls[i], dbInit);
343 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
345 if(getuid() == OWNER_ROOT && AIL_ERROR_OK != ail_db_change_perm(db, uid)) {
346 _E("Failed to change permission\n");
350 _E("Failed to create table %s\n", db);
354 ret = sqlite3_close(dbInit);
355 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
358 if(mode & DB_OPEN_RO) {
359 if(uid != GLOBAL_USER) {
360 if (!db_info.dbUserro) {
361 db_util_open_with_options(db, &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
362 char query_attach[AIL_SQL_QUERY_MAX_LEN];
363 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
364 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
365 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, global_db);
366 if (db_exec_usr_ro(query_attach) < 0) {
367 _D("executing query_attach : %s", query_attach );
370 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
371 if (db_exec_usr_ro(query_view_app) < 0) {
372 _D("executing query_attach : %s", query_view_app );
376 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
377 if (db_exec_usr_ro(query_view_local) < 0) {
378 _D("executing query_attach : %s", query_view_local );
383 if (!db_info.dbGlobalro) {
384 ret = db_util_open_with_options(global_db, &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
385 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
389 if(mode & DB_OPEN_RW) {
390 if(uid != GLOBAL_USER) {
391 if(!db_info.dbUserrw){
392 ret = db_util_open(db, &db_info.dbUserrw, 0);
395 if(!db_info.dbGlobalrw){
396 ret = db_util_open(global_db, &db_info.dbGlobalrw, 0);
399 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
411 return AIL_ERROR_DB_FAILED;
415 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
417 return db_do_prepare(db_info.dbUserro, query, stmt);
420 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
422 return db_do_prepare(db_info.dbGlobalro, query, stmt);
425 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
427 return db_do_prepare(db_info.dbUserrw, query, stmt);
431 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
433 return db_do_prepare(db_info.dbGlobalrw, query, stmt);
437 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
441 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
443 ret = sqlite3_bind_int(stmt, idx, (int) value);
444 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
451 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
455 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
457 ret = sqlite3_bind_int(stmt, idx, value);
458 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
463 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
467 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
469 ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
470 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
476 ail_error_e db_step(sqlite3_stmt *stmt)
480 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
482 ret = sqlite3_step(stmt);
485 return AIL_ERROR_NO_DATA;
490 retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
495 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
499 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
500 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
502 out_val = sqlite3_column_int(stmt, index);
503 *value = (out_val == 1)? true:false;
510 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
512 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
513 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
515 *value = sqlite3_column_int(stmt, index);
522 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
524 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
525 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
527 *str = (char *)sqlite3_column_text(stmt, index);
534 ail_error_e db_reset(sqlite3_stmt *stmt)
538 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
540 sqlite3_clear_bindings(stmt);
542 ret = sqlite3_reset(stmt);
543 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
550 ail_error_e db_finalize(sqlite3_stmt *stmt)
554 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
556 ret = sqlite3_finalize(stmt);
557 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
564 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
569 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
570 retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
572 ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
573 if (ret != SQLITE_OK) {
574 _E("Cannot execute this query - %s. because %s",
575 query, errmsg? errmsg:"uncatched error");
577 sqlite3_free(errmsg);
578 return AIL_ERROR_DB_FAILED;
586 ail_error_e db_exec_usr_rw(const char *query)
588 return do_db_exec(query, db_info.dbUserrw);
592 ail_error_e db_exec_usr_ro(const char *query)
594 return do_db_exec(query, db_info.dbUserro);
597 ail_error_e db_exec_glo_ro(const char *query)
599 return do_db_exec(query, db_info.dbGlobalro);
602 ail_error_e db_exec_glo_rw(const char *query)
604 return do_db_exec(query, db_info.dbGlobalrw);
608 ail_error_e db_close(void)
612 if(db_info.dbUserro) {
613 ret = sqlite3_close(db_info.dbUserro);
614 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
616 db_info.dbUserro = NULL;
618 if(db_info.dbGlobalrw) {
619 ret = sqlite3_close(db_info.dbGlobalrw);
620 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
622 db_info.dbGlobalrw = NULL;
624 if(db_info.dbUserrw) {
625 ret = sqlite3_close(db_info.dbUserrw);
626 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
628 db_info.dbUserrw = NULL;
634 EXPORT_API ail_error_e ail_db_close(void)
639 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
641 char *error_message = NULL;
642 if(db_info.dbGlobalro) {
644 sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
645 _E("Don't execute query = %s error message = %s\n", query,
647 sqlite3_free(error_message);
651 if(db_info.dbUserro) {
653 sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
654 _E("Don't execute query = %s error message = %s\n", query,
656 sqlite3_free(error_message);
660 sqlite3_free(error_message);