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) \
47 if (smack_setlabel((x), (((uid) == GLOBAL_USER) ? "*" : "User"), SMACK_LABEL_ACCESS)) \
48 _E("failed chsmack -a \"User/*\" %s", x); \
50 _D("chsmack -a \"User/*\" %s", x); \
53 #define retv_with_dbmsg_if(expr, val) \
56 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
57 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
58 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
59 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
60 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
61 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
62 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
63 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
68 #define tryvm_with_dbmsg_if(expr, val) \
71 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
72 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
73 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
74 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
75 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
76 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
77 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
78 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
83 static __thread struct {
95 static __thread sqlite3 *dbInit = NULL;
97 static int ail_db_change_perm(const char *db_file, uid_t uid)
100 char journal_file[BUFSIZE];
105 struct passwd *userinfo = NULL;
106 char *pwd_buf = NULL;
109 files[0] = (char *)db_file;
110 files[1] = journal_file;
113 retv_if(!db_file, AIL_ERROR_FAIL);
114 if (getuid() != OWNER_ROOT) /* At this time we should be root to apply this */
117 pwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
118 if (pwd_bufsize <= 0)
121 pwd_buf = (char *)malloc(pwd_bufsize);
122 if (pwd_buf == NULL) {
124 return AIL_ERROR_OUT_OF_MEMORY;
127 if (getpwuid_r(uid, &pwd, pwd_buf, pwd_bufsize, &userinfo) != 0) {
128 _E("FAIL: user %d doesn't exist", uid);
130 return AIL_ERROR_FAIL;
132 snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
134 for (i = 0; files[i]; i++) {
135 /* Compare git_t type and not group name */
136 ret = chown(files[i], uid, userinfo->pw_gid);
137 SET_SMACK_LABEL(files[i],uid);
139 strerror_r(errno, buf, sizeof(buf));
140 _E("FAIL : chown %s %d.%d, because %s", db_file, uid, userinfo->pw_gid, buf);
142 return AIL_ERROR_FAIL;
145 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
147 strerror_r(errno, buf, sizeof(buf));
148 _E("FAIL : chmod %s 0664, because %s", db_file, buf);
150 return AIL_ERROR_FAIL;
159 char *ail_get_icon_path(uid_t uid)
163 struct group *grpinfo = NULL;
166 struct passwd *userinfo = NULL;
172 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
176 if (uid != GLOBAL_USER) {
177 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
181 pwd_buf = (char *)malloc(buflen);
182 if (pwd_buf == NULL) {
187 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
188 _E("getpwuid(%d) returns NULL !", uid);
193 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
197 buf = (char *)malloc(buflen);
204 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
205 _E("getgrnam_r(users) returns NULL !");
211 /* Compare git_t type and not group name */
212 if (grpinfo->gr_gid != userinfo->pw_gid) {
213 _E("UID [%d] does not belong to 'users' group!", uid);
219 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
222 result = strdup(tzplatform_mkpath(TZ_SYS_RW_ICONS, "/"));
223 if (result == NULL) {
229 int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
230 if (ret == -1 && errno != EEXIST) {
231 _E("FAIL : to create directory %s %d", result, errno);
232 } else if (getuid() == OWNER_ROOT) {
233 ret = chown(result, uid, grpinfo ? grpinfo->gr_gid : 0);
234 SET_SMACK_LABEL(result, uid);
237 strerror_r(errno, buf, sizeof(buf));
238 _E("FAIL : chown %s %d.%d, because %s", result, uid,
239 grpinfo ? grpinfo->gr_gid : 0, buf);
248 char *ail_get_app_DB_journal(uid_t uid)
250 char *app_path = ail_get_app_DB(uid);
253 asprintf(&result, "%s-journal", app_path);
259 char *ail_get_app_DB(uid_t uid)
263 struct group *grpinfo = NULL;
267 struct passwd *userinfo;
273 _E("FAIL : Root is not allowed! switch to DEFAULT_USER");
277 if (uid != GLOBAL_USER) {
278 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
282 pwd_buf = (char *)malloc(buflen);
283 if (pwd_buf == NULL) {
288 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
289 _E("getpwuid(%d) returns NULL !", uid);
294 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
298 buf = (char *)malloc(buflen);
305 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
306 _E("getgrnam(users) returns NULL !");
312 /* Compare git_t type and not group name */
313 if (grpinfo->gr_gid != userinfo->pw_gid) {
314 _E("UID [%d] does not belong to 'users' group!", uid);
320 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
323 result = strdup(APP_INFO_DB_FILE);
324 if (result == NULL) {
330 temp = strdup(result);
336 dir = strrchr(temp, '/');
344 int ret = mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
345 if (ret == -1 && errno != EEXIST) {
346 _E("FAIL : to create directory %s %d", temp, errno);
347 } else if (getuid() == OWNER_ROOT) {
348 ret = chown(temp, uid, grpinfo ? grpinfo->gr_gid : 0);
349 SET_SMACK_LABEL(temp,uid);
352 strerror_r(errno, buf, sizeof(buf));
353 _E("FAIL : chown %s %d.%d, because %s", temp, uid,
354 grpinfo ? grpinfo->gr_gid : 0, buf);
364 char *ail_get_desktop_path(uid_t uid)
368 struct group *grpinfo = NULL;
371 struct passwd *userinfo = NULL;
377 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
381 if (uid != GLOBAL_USER) {
382 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
386 pwd_buf = (char *)malloc(buflen);
387 if (pwd_buf == NULL) {
392 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
393 _E("getpwuid(%d) returns NULL !", uid);
398 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
402 buf = (char *)malloc(buflen);
409 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
410 _E("getgrnam(users) returns NULL !");
416 /* Compare git_t type and not group name */
417 if (grpinfo->gr_gid != userinfo->pw_gid) {
418 _E("UID [%d] does not belong to 'users' group!", uid);
424 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
427 result = strdup(tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/"));
428 if (result == NULL) {
434 int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
435 if (ret == -1 && errno != EEXIST) {
436 _E("FAIL : to create directory %s %d", result, errno);
437 } else if (getuid() == OWNER_ROOT) {
438 ret = chown(result, uid, grpinfo ? grpinfo->gr_gid : 0);
439 SET_SMACK_LABEL(result,uid);
442 strerror_r(errno, buf, sizeof(buf));
443 _E("FAIL : chown %s %d.%d, because %s", result, uid,
444 grpinfo ? grpinfo->gr_gid : 0, buf);
454 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
458 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
459 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
460 retv_if(!db, AIL_ERROR_DB_FAILED);
462 ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
463 if (ret != SQLITE_OK) {
464 _E("%s\n", sqlite3_errmsg(db));
465 return AIL_ERROR_DB_FAILED;
470 ail_error_e db_open(db_open_mode mode, uid_t uid)
477 const char *tbls[3] = {
478 "CREATE TABLE app_info "
479 "(package TEXT PRIMARY KEY, "
480 "exec TEXT DEFAULT 'No Exec', "
481 "name TEXT DEFAULT 'No Name', "
482 "type TEXT DEFAULT 'Application', "
483 "icon TEXT DEFAULT 'No Icon', "
487 "x_slp_service TEXT, "
488 "x_slp_packagetype TEXT, "
489 "x_slp_packagecategories TEXT, "
490 "x_slp_packageid TEXT, "
493 "x_slp_exe_path TEXT, "
496 "x_slp_domain TEXT, "
497 "x_slp_submodemainid TEXT, "
498 "x_slp_installedstorage TEXT, "
499 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
500 "x_slp_installedtime INTEGER DEFAULT 0, "
501 "nodisplay INTEGER DEFAULT 0, "
502 "x_slp_taskmanage INTEGER DEFAULT 1, "
503 "x_slp_multiple INTEGER DEFAULT 0, "
504 "x_slp_removable INTEGER DEFAULT 1, "
505 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
506 "x_slp_enabled INTEGER DEFAULT 1, "
507 "x_slp_submode INTEGER DEFAULT 0, "
508 "desktop TEXT UNIQUE NOT NULL);",
509 "CREATE TABLE localname (package TEXT NOT NULL, "
510 "locale TEXT NOT NULL, "
511 "name TEXT NOT NULL, "
512 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
517 db = ail_get_app_DB(uid);
519 _E("Failed to get app DB");
520 return AIL_ERROR_DB_FAILED;
523 global_db = ail_get_app_DB(GLOBAL_USER);
524 if (global_db == NULL) {
525 _E("Failed to get global app DB");
527 return AIL_ERROR_DB_FAILED;
530 if (access(db, F_OK)) {
531 if (AIL_ERROR_OK == db_util_open_with_options(db, &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
533 for (i = 0; tbls[i] != NULL; i++) {
534 ret = do_db_exec(tbls[i], dbInit);
535 if (ret != AIL_ERROR_OK)
538 if(getuid() == OWNER_ROOT && AIL_ERROR_OK != ail_db_change_perm(db, uid)) {
539 _E("Failed to change permission\n");
543 _E("Failed to create table %s\n", db);
548 ret = sqlite3_close(dbInit);
549 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
552 if(mode & DB_OPEN_RO) {
553 if(uid != GLOBAL_USER) {
554 if (!db_info.dbUserro) {
555 db_util_open_with_options(db, &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
556 char query_attach[AIL_SQL_QUERY_MAX_LEN];
557 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
558 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
559 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, global_db);
560 if (db_exec_usr_ro(query_attach) < 0) {
561 _D("executing query_attach : %s", query_attach);
564 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
565 if (db_exec_usr_ro(query_view_app) < 0) {
566 _D("executing query_attach : %s", query_view_app);
570 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
571 if (db_exec_usr_ro(query_view_local) < 0) {
572 _D("executing query_attach : %s", query_view_local);
577 if (!db_info.dbGlobalro) {
578 ret = db_util_open_with_options(global_db, &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
579 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
584 if (mode & DB_OPEN_RW) {
585 if (uid != GLOBAL_USER) {
586 if (!db_info.dbUserrw) {
587 ret = db_util_open(db, &db_info.dbUserrw, 0);
588 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
591 if (!db_info.dbGlobalrw) {
592 ret = db_util_open(global_db, &db_info.dbGlobalrw, 0);
593 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
607 return AIL_ERROR_DB_FAILED;
610 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
612 return db_do_prepare(db_info.dbUserro, query, stmt);
615 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
617 return db_do_prepare(db_info.dbGlobalro, query, stmt);
620 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
622 return db_do_prepare(db_info.dbUserrw, query, stmt);
625 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
627 return db_do_prepare(db_info.dbGlobalrw, query, stmt);
630 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
634 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
636 ret = sqlite3_bind_int(stmt, idx, (int) value);
637 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
642 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
646 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
648 ret = sqlite3_bind_int(stmt, idx, value);
649 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
654 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
658 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
660 ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
661 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
666 ail_error_e db_step(sqlite3_stmt *stmt)
670 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
672 ret = sqlite3_step(stmt);
675 return AIL_ERROR_NO_DATA;
680 retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
683 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
687 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
688 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
690 out_val = sqlite3_column_int(stmt, index);
691 *value = (out_val == 1)? true:false;
696 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
698 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
699 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
701 *value = sqlite3_column_int(stmt, index);
706 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
708 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
709 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
711 *str = (char *)sqlite3_column_text(stmt, index);
716 ail_error_e db_reset(sqlite3_stmt *stmt)
720 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
722 sqlite3_clear_bindings(stmt);
724 ret = sqlite3_reset(stmt);
725 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
730 ail_error_e db_finalize(sqlite3_stmt *stmt)
734 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
736 ret = sqlite3_finalize(stmt);
737 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
742 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
747 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
748 retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
750 ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
751 if (ret != SQLITE_OK) {
752 _E("Cannot execute this query - %s. because %s",
753 query, errmsg? errmsg:"uncatched error");
755 sqlite3_free(errmsg);
756 return AIL_ERROR_DB_FAILED;
762 ail_error_e db_exec_usr_rw(const char *query)
764 return do_db_exec(query, db_info.dbUserrw);
767 ail_error_e db_exec_usr_ro(const char *query)
769 return do_db_exec(query, db_info.dbUserro);
772 ail_error_e db_exec_glo_ro(const char *query)
774 return do_db_exec(query, db_info.dbGlobalro);
777 ail_error_e db_exec_glo_rw(const char *query)
779 return do_db_exec(query, db_info.dbGlobalrw);
782 ail_error_e db_close(void)
786 if(db_info.dbUserro) {
787 ret = sqlite3_close(db_info.dbUserro);
788 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
790 db_info.dbUserro = NULL;
792 if(db_info.dbGlobalrw) {
793 ret = sqlite3_close(db_info.dbGlobalrw);
794 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
796 db_info.dbGlobalrw = NULL;
798 if(db_info.dbUserrw) {
799 ret = sqlite3_close(db_info.dbUserrw);
800 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
802 db_info.dbUserrw = NULL;
808 EXPORT_API ail_error_e ail_db_close(void)
813 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
815 char *error_message = NULL;
816 if(db_info.dbGlobalro) {
818 sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
819 _E("Don't execute query = %s error message = %s\n", query,
821 sqlite3_free(error_message);
825 if(db_info.dbUserro) {
827 sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
828 _E("Don't execute query = %s error message = %s\n", query,
830 sqlite3_free(error_message);
834 sqlite3_free(error_message);