Remove setuid bit
[platform/core/appfw/ail.git] / src / ail_db.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #define _GNU_SOURCE
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <db-util.h>
27 #include <errno.h>
28 #include <glib.h>
29 #include <grp.h>
30 #include <pwd.h>
31 #include <sys/smack.h>
32 #include <sys/stat.h>
33 #include <tzplatform_config.h>
34 #include "ail_private.h"
35 #include "ail_db.h"
36
37 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
38 #define BUFSIZE 4096
39 #define QUERY_ATTACH "attach database '%s' as Global"
40 #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)"
41
42 #define QUERY_CREATE_VIEW_LOCAL "CREATE temp VIEW localname as select distinct * from (select  * from main.localname m union select * from Global.localname g)"
43
44 #define SET_SMACK_LABEL(x, uid) \
45         do { \
46                 if (smack_setlabel((x), (((uid) == GLOBAL_USER) ? "*" : "User"), SMACK_LABEL_ACCESS)) \
47                         _E("failed chsmack -a \"User/*\" %s", x); \
48                 else \
49                         _D("chsmack -a \"User/*\" %s", x); \
50         } while (0)
51
52 #define retv_with_dbmsg_if(expr, val) \
53         do { \
54                 if (expr) { \
55                         _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
56                         _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
57                         _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
58                         _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
59                         _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
60                         _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
61                         _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
62                         _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
63                         return (val); \
64                 } \
65         } while (0)
66
67 #define tryvm_with_dbmsg_if(expr, val) \
68         do { \
69                 if (expr) { \
70                         _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
71                         _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
72                         _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
73                         _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
74                         _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
75                         _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
76                         _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
77                         _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
78                         goto catch; \
79                 } \
80         } while (0)
81
82 static __thread struct {
83         sqlite3 *dbUserro;
84         sqlite3 *dbGlobalro;
85         sqlite3 *dbUserrw;
86         sqlite3 *dbGlobalrw;
87 } db_info = {
88         .dbUserro = NULL,
89         .dbGlobalro = NULL,
90         .dbUserrw = NULL,
91         .dbGlobalrw = NULL
92 };
93
94 static __thread sqlite3 *dbInit = NULL;
95
96 static int ail_db_change_perm(const char *db_file, uid_t uid)
97 {
98         char journal_file[BUFSIZE];
99         char *files[3];
100         int ret;
101         int i;
102         struct passwd pwd;
103         struct passwd *userinfo = NULL;
104         char *pwd_buf = NULL;
105         int pwd_bufsize;
106
107         files[0] = (char *)db_file;
108         files[1] = journal_file;
109         files[2] = NULL;
110
111         retv_if(!db_file, AIL_ERROR_FAIL);
112         if (getuid() != OWNER_ROOT) /* At this time we should be root to apply this */
113                 return AIL_ERROR_OK;
114
115         pwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
116         if (pwd_bufsize <= 0)
117                 pwd_bufsize = 16384;
118
119         pwd_buf = (char *)malloc(pwd_bufsize);
120         if (pwd_buf == NULL) {
121                 _E("out of memory");
122                 return AIL_ERROR_OUT_OF_MEMORY;
123         }
124
125         if (getpwuid_r(uid, &pwd, pwd_buf, pwd_bufsize, &userinfo) != 0) {
126                 _E("FAIL: user %d doesn't exist", uid);
127                 free(pwd_buf);
128                 return AIL_ERROR_FAIL;
129         }
130         snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
131
132         for (i = 0; files[i]; i++) {
133                 /* Compare git_t type and not group name */
134                 ret = chown(files[i], uid, userinfo->pw_gid);
135                 SET_SMACK_LABEL(files[i], uid);
136                 if (ret == -1) {
137                         _E("FAIL : chown %s %d.%d, because %d", db_file, uid, userinfo->pw_gid, errno);
138                         free(pwd_buf);
139                         return AIL_ERROR_FAIL;
140                 }
141
142                 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
143                 if (ret == -1) {
144                         _E("FAIL : chmod %s 0664, because %d", db_file, errno);
145                         free(pwd_buf);
146                         return AIL_ERROR_FAIL;
147                 }
148         }
149
150         free(pwd_buf);
151
152         return AIL_ERROR_OK;
153 }
154
155 char *ail_get_icon_path(uid_t uid)
156 {
157         char *result = NULL;
158         struct group grpbuf;
159         struct group *grpinfo = NULL;
160         struct passwd pwd;
161         struct passwd *userinfo = NULL;
162         int buflen;
163         char *buf = NULL;
164         char *pwd_buf;
165
166         if (uid == 0) {
167                 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
168                 return NULL;
169         }
170
171         if (uid != GLOBAL_USER) {
172                 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
173                 if (buflen <= 0)
174                         buflen = 16384;
175
176                 pwd_buf = (char *)malloc(buflen);
177                 if (pwd_buf == NULL) {
178                         _E("out of memory");
179                         return NULL;
180                 }
181
182                 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
183                         _E("getpwuid(%d) returns NULL !", uid);
184                         free(pwd_buf);
185                         return NULL;
186                 }
187
188                 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
189                 if (buflen <= 0)
190                         buflen = 1024;
191
192                 buf = (char *)malloc(buflen);
193                 if (buf == NULL) {
194                         _E("out of memory");
195                         free(pwd_buf);
196                         return NULL;
197                 }
198
199                 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
200                         _E("getgrnam_r(users) returns NULL !");
201                         free(pwd_buf);
202                         free(buf);
203                         return NULL;
204                 }
205
206                 /* Compare git_t type and not group name */
207                 if (grpinfo->gr_gid != userinfo->pw_gid) {
208                         _E("UID [%d] does not belong to 'users' group!", uid);
209                         free(pwd_buf);
210                         free(buf);
211                         return NULL;
212                 }
213
214                 if (asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir) == -1)
215                         _E("out of memory: asprintf() is failed.");
216
217                 free(pwd_buf);
218         } else {
219                 result = strdup(tzplatform_mkpath(TZ_SYS_RW_ICONS, "/"));
220                 if (result == NULL) {
221                         _E("out of memory");
222                         return NULL;
223                 }
224         }
225
226         int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
227         if (ret == -1 && errno != EEXIST) {
228                 _E("FAIL : to create directory %s %d", result, errno);
229         } else if (getuid() == OWNER_ROOT) {
230                 ret = chown(result, uid, grpinfo ? grpinfo->gr_gid : 0);
231                 SET_SMACK_LABEL(result, uid);
232                 if (ret == -1) {
233                         _E("FAIL : chown %s %d.%d, because %d", result, uid,
234                                         grpinfo ? grpinfo->gr_gid : 0, errno);
235                 }
236         }
237
238         free(buf);
239
240         return result;
241 }
242
243 char *ail_get_app_DB_journal(uid_t uid)
244 {
245         char *app_path = ail_get_app_DB(uid);
246         char *result = NULL;
247
248         if (asprintf(&result, "%s-journal", app_path) == -1)
249                 _E("out of memory: asprintf() is failed.");
250
251         free(app_path);
252
253         return  result;
254 }
255
256 char *ail_get_app_DB(uid_t uid)
257 {
258         char *result = NULL;
259         struct group grpbuf;
260         struct group *grpinfo = NULL;
261         char *dir = NULL;
262         char *temp = NULL;
263         struct passwd pwd;
264         struct passwd *userinfo;
265         int buflen;
266         char *buf = NULL;
267         char *pwd_buf;
268
269         if (uid == 0) {
270                 _E("FAIL : Root is not allowed! switch to DEFAULT_USER");
271                 return NULL;
272         }
273
274         if (uid != GLOBAL_USER) {
275                 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
276                 if (buflen <= 0)
277                         buflen = 16384;
278
279                 pwd_buf = (char *)malloc(buflen);
280                 if (pwd_buf == NULL) {
281                         _E("out of memory");
282                         return NULL;
283                 }
284
285                 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
286                         _E("getpwuid(%d) returns NULL !", uid);
287                         free(pwd_buf);
288                         return NULL;
289                 }
290
291                 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
292                 if (buflen <= 0)
293                         buflen = 1024;
294
295                 buf = (char *)malloc(buflen);
296                 if (buf == NULL) {
297                         _E("out of memory");
298                         free(pwd_buf);
299                         return NULL;
300                 }
301
302                 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
303                         _E("getgrnam(users) returns NULL !");
304                         free(pwd_buf);
305                         free(buf);
306                         return NULL;
307                 }
308
309                 /* Compare git_t type and not group name */
310                 if (grpinfo->gr_gid != userinfo->pw_gid) {
311                         _E("UID [%d] does not belong to 'users' group!", uid);
312                         free(pwd_buf);
313                         free(buf);
314                         return NULL;
315                 }
316
317                 if (asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir) == -1)
318                         _E("out of memory: asprintf() is failed.");
319
320                 free(pwd_buf);
321         } else {
322                 result = strdup(APP_INFO_DB_FILE);
323                 if (result == NULL) {
324                         _E("ouf of memory");
325                         return NULL;
326                 }
327         }
328
329         temp = strdup(result);
330         if (temp == NULL) {
331                 free(buf);
332                 return result;
333         }
334
335         dir = strrchr(temp, '/');
336         if (!dir) {
337                 free(temp);
338                 free(buf);
339                 return result;
340         }
341         *dir = 0;
342
343         int ret = mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
344         if (ret == -1 && errno != EEXIST) {
345                 _E("FAIL : to create directory %s %d", temp, errno);
346         } else if (getuid() == OWNER_ROOT) {
347                 ret = chown(temp, uid, grpinfo ? grpinfo->gr_gid : 0);
348                 SET_SMACK_LABEL(temp, uid);
349                 if (ret == -1) {
350                         _E("FAIL : chown %s %d.%d, because %d", temp, uid,
351                                         grpinfo ? grpinfo->gr_gid : 0, errno);
352                 }
353         }
354
355         free(temp);
356         free(buf);
357
358         return result;
359 }
360
361 char *ail_get_desktop_path(uid_t uid)
362 {
363         char *result = NULL;
364         struct group grpbuf;
365         struct group *grpinfo = NULL;
366         struct passwd pwd;
367         struct passwd *userinfo = NULL;
368         int buflen;
369         char *buf = NULL;
370         char *pwd_buf;
371
372         if (uid == 0) {
373                 _E("FAIL : Root is not allowed user! please fix it replacing with DEFAULT_USER");
374                 return NULL;
375         }
376
377         if (uid != GLOBAL_USER) {
378                 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
379                 if (buflen <= 0)
380                         buflen = 16384;
381
382                 pwd_buf = (char *)malloc(buflen);
383                 if (pwd_buf == NULL) {
384                         _E("out of memory");
385                         return NULL;
386                 }
387
388                 if (getpwuid_r(uid, &pwd, pwd_buf, buflen, &userinfo) != 0) {
389                         _E("getpwuid(%d) returns NULL !", uid);
390                         free(pwd_buf);
391                         return NULL;
392                 }
393
394                 buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
395                 if (buflen <= 0)
396                         buflen = 1024;
397
398                 buf = (char *)malloc(buflen);
399                 if (buf == NULL) {
400                         _E("out of memory");
401                         free(pwd_buf);
402                         return NULL;
403                 }
404
405                 if (getgrnam_r("users", &grpbuf, buf, buflen, &grpinfo) != 0) {
406                         _E("getgrnam(users) returns NULL !");
407                         free(pwd_buf);
408                         free(buf);
409                         return NULL;
410                 }
411
412                 /* Compare git_t type and not group name */
413                 if (grpinfo->gr_gid != userinfo->pw_gid) {
414                         _E("UID [%d] does not belong to 'users' group!", uid);
415                         free(pwd_buf);
416                         free(buf);
417                         return NULL;
418                 }
419
420                 if (asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir) == -1)
421                         _E("out of memory: asprintf() is failed.");
422
423                 free(pwd_buf);
424         } else {
425                 result = strdup(tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/"));
426                 if (result == NULL) {
427                         _E("out of memory");
428                         return NULL;
429                 }
430         }
431
432         int ret = mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
433         if (ret == -1 && errno != EEXIST) {
434                 _E("FAIL : to create directory %s %d", result, errno);
435         } else if (getuid() == OWNER_ROOT) {
436                 ret = chown(result, uid, grpinfo ? grpinfo->gr_gid : 0);
437                 SET_SMACK_LABEL(result, uid);
438                 if (ret == -1) {
439                         _E("FAIL : chown %s %d.%d, because %d", result, uid,
440                                         grpinfo ? grpinfo->gr_gid : 0, errno);
441                 }
442         }
443
444         free(buf);
445
446         return result;
447 }
448
449
450 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
451 {
452         int ret;
453
454         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
455         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
456         retv_if(!db, AIL_ERROR_DB_FAILED);
457
458         ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
459         if (ret != SQLITE_OK) {
460                 _E("%s\n", sqlite3_errmsg(db));
461                 return AIL_ERROR_DB_FAILED;
462         } else
463                 return AIL_ERROR_OK;
464 }
465
466 ail_error_e db_open(db_open_mode mode, uid_t uid)
467 {
468         int ret;
469         int i;
470         char *db;
471         char *global_db;
472         const char *tbls[3] = {
473                 "CREATE TABLE app_info "
474                 "(package TEXT PRIMARY KEY, "
475                 "exec TEXT DEFAULT 'No Exec', "
476                 "name TEXT DEFAULT 'No Name', "
477                 "type TEXT DEFAULT 'Application', "
478                 "icon TEXT DEFAULT 'No Icon', "
479                 "categories TEXT, "
480                 "version TEXT, "
481                 "mimetype TEXT, "
482                 "x_slp_service TEXT, "
483                 "x_slp_packagetype TEXT, "
484                 "x_slp_packagecategories TEXT, "
485                 "x_slp_packageid TEXT, "
486                 "x_slp_uri TEXT, "
487                 "x_slp_svc TEXT, "
488                 "x_slp_exe_path TEXT, "
489                 "x_slp_appid TEXT, "
490                 "x_slp_pkgid TEXT, "
491                 "x_slp_domain TEXT, "
492                 "x_slp_submodemainid TEXT, "
493                 "x_slp_installedstorage TEXT, "
494                 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
495                 "x_slp_installedtime INTEGER DEFAULT 0, "
496                 "nodisplay INTEGER DEFAULT 0, "
497                 "x_slp_taskmanage INTEGER DEFAULT 1, "
498                 "x_slp_multiple INTEGER DEFAULT 0, "
499                 "x_slp_removable INTEGER DEFAULT 1, "
500                 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
501                 "x_slp_enabled INTEGER DEFAULT 1, "
502                 "x_slp_submode INTEGER DEFAULT 0, "
503                 "desktop TEXT UNIQUE NOT NULL);",
504                 "CREATE TABLE localname (package TEXT NOT NULL, "
505                 "locale TEXT NOT NULL, "
506                 "name TEXT NOT NULL, "
507                 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
508
509                 NULL
510         };
511
512         db = ail_get_app_DB(uid);
513         if (db == NULL) {
514                 _E("Failed to get app DB");
515                 return AIL_ERROR_DB_FAILED;
516         }
517
518         global_db = ail_get_app_DB(GLOBAL_USER);
519         if (global_db == NULL) {
520                 _E("Failed to get global app DB");
521                 free(db);
522                 return AIL_ERROR_DB_FAILED;
523         }
524
525         if (access(db, F_OK)) {
526                 if (AIL_ERROR_OK == db_util_open_with_options(db,
527                                         &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
528                         for (i = 0; tbls[i] != NULL; i++) {
529                                 ret = do_db_exec(tbls[i], dbInit);
530                                 if (ret != AIL_ERROR_OK)
531                                         goto catch;
532                         }
533                         if (getuid() == OWNER_ROOT && AIL_ERROR_OK != ail_db_change_perm(db, uid))
534                                 _E("Failed to change permission\n");
535                 } else {
536                         dbInit = NULL;
537                         _E("Failed to create table %s\n", db);
538                 }
539         }
540
541         if (dbInit) {
542                 ret = sqlite3_close(dbInit);
543                 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
544                 dbInit = NULL;
545         }
546         if (mode & DB_OPEN_RO) {
547                 if (uid != GLOBAL_USER) {
548                         if (!db_info.dbUserro) {
549                                 db_util_open_with_options(db, &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
550                                 char query_attach[AIL_SQL_QUERY_MAX_LEN];
551                                 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
552                                 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
553                                 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, global_db);
554                                 if (db_exec_usr_ro(query_attach) < 0) {
555                                         _D("executing query_attach : %s", query_attach);
556                                         goto catch;
557                                 }
558                                 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
559                                 if (db_exec_usr_ro(query_view_app) < 0) {
560                                         _D("executing query_attach : %s", query_view_app);
561                                         goto catch;
562                                 }
563
564                                 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
565                                 if (db_exec_usr_ro(query_view_local) < 0) {
566                                         _D("executing query_attach : %s", query_view_local);
567                                         goto catch;
568                                 }
569                         }
570                 } else {
571                         if (!db_info.dbGlobalro) {
572                                 ret = db_util_open_with_options(global_db, &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
573                                 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
574                         }
575                 }
576         }
577
578         if (mode & DB_OPEN_RW) {
579                 if (uid != GLOBAL_USER) {
580                         if (!db_info.dbUserrw) {
581                                 ret = db_util_open(db, &db_info.dbUserrw, 0);
582                                 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
583                         }
584                 } else {
585                         if (!db_info.dbGlobalrw) {
586                                 ret = db_util_open(global_db, &db_info.dbGlobalrw, 0);
587                                 tryvm_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
588                         }
589                 }
590         }
591
592         free(global_db);
593         free(db);
594
595         return AIL_ERROR_OK;
596
597 catch:
598         free(global_db);
599         free(db);
600
601         return AIL_ERROR_DB_FAILED;
602 }
603
604 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
605 {
606         return db_do_prepare(db_info.dbUserro, query, stmt);
607 }
608
609 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
610 {
611         return db_do_prepare(db_info.dbGlobalro, query, stmt);
612 }
613
614 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
615 {
616         return db_do_prepare(db_info.dbUserrw, query, stmt);
617 }
618
619 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
620 {
621         return db_do_prepare(db_info.dbGlobalrw, query, stmt);
622 }
623
624 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
625 {
626         int ret;
627
628         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
629
630         ret = sqlite3_bind_int(stmt, idx, (int) value);
631         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
632
633         return AIL_ERROR_OK;
634 }
635
636 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
637 {
638         int ret;
639
640         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
641
642         ret = sqlite3_bind_int(stmt, idx, value);
643         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
644
645         return AIL_ERROR_OK;
646 }
647
648 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, const char* value)
649 {
650         int ret;
651
652         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
653
654         ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
655         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
656
657         return AIL_ERROR_OK;
658 }
659
660 ail_error_e db_step(sqlite3_stmt *stmt)
661 {
662         int ret;
663
664         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
665
666         ret = sqlite3_step(stmt);
667         switch (ret) {
668         case SQLITE_DONE:
669                 return AIL_ERROR_NO_DATA;
670         case SQLITE_ROW:
671                 return AIL_ERROR_OK;
672         }
673
674         retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
675 }
676
677 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
678 {
679         int out_val;
680
681         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
682         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
683
684         out_val = sqlite3_column_int(stmt, index);
685         *value = (out_val == 1) ? true : false;
686
687         return AIL_ERROR_OK;
688 }
689
690 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
691 {
692         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
693         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
694
695         *value = sqlite3_column_int(stmt, index);
696
697         return AIL_ERROR_OK;
698 }
699
700 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
701 {
702         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
703         retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
704
705         *str = (char *)sqlite3_column_text(stmt, index);
706
707         return AIL_ERROR_OK;
708 }
709
710 ail_error_e db_reset(sqlite3_stmt *stmt)
711 {
712         int ret;
713
714         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
715
716         sqlite3_clear_bindings(stmt);
717
718         ret = sqlite3_reset(stmt);
719         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
720
721         return AIL_ERROR_OK;
722 }
723
724 ail_error_e db_finalize(sqlite3_stmt *stmt)
725 {
726         int ret;
727
728         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
729
730         ret = sqlite3_finalize(stmt);
731         retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
732
733         return AIL_ERROR_OK;
734 }
735
736 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
737 {
738         int ret;
739         char *errmsg = NULL;
740
741         retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
742         retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
743
744         ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
745         if (ret != SQLITE_OK) {
746                 _E("Cannot execute this query - %s. because %s",
747                                 query, errmsg ? errmsg : "uncatched error");
748                 if (errmsg)
749                         sqlite3_free(errmsg);
750                 return AIL_ERROR_DB_FAILED;
751         }
752
753         return AIL_ERROR_OK;
754 }
755
756 ail_error_e db_exec_usr_rw(const char *query)
757 {
758         return do_db_exec(query, db_info.dbUserrw);
759 }
760
761 ail_error_e db_exec_usr_ro(const char *query)
762 {
763         return do_db_exec(query, db_info.dbUserro);
764 }
765
766 ail_error_e db_exec_glo_ro(const char *query)
767 {
768         return do_db_exec(query, db_info.dbGlobalro);
769 }
770
771 ail_error_e db_exec_glo_rw(const char *query)
772 {
773         return do_db_exec(query, db_info.dbGlobalrw);
774 }
775
776 ail_error_e db_close(void)
777 {
778         int ret;
779
780         if (db_info.dbUserro) {
781                 ret = sqlite3_close(db_info.dbUserro);
782                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
783                 db_info.dbUserro = NULL;
784         }
785
786         if (db_info.dbGlobalrw) {
787                 ret = sqlite3_close(db_info.dbGlobalrw);
788                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
789                 db_info.dbGlobalrw = NULL;
790         }
791
792         if (db_info.dbUserrw) {
793                 ret = sqlite3_close(db_info.dbUserrw);
794                 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
795                 db_info.dbUserrw = NULL;
796         }
797
798         return AIL_ERROR_OK;
799 }
800
801 EXPORT_API ail_error_e ail_db_close(void)
802 {
803         return db_close();
804 }
805
806 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
807 {
808         char *error_message = NULL;
809         if (db_info.dbGlobalro) {
810                 if (SQLITE_OK !=
811                         sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
812                         _E("Don't execute query = %s error message = %s\n", query,
813                                 error_message);
814                         sqlite3_free(error_message);
815                         return -1;
816                 }
817         }
818         if (db_info.dbUserro) {
819                 if (SQLITE_OK !=
820                         sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
821                         _E("Don't execute query = %s error message = %s\n", query,
822                                 error_message);
823                         sqlite3_free(error_message);
824                         return -1;
825                 }
826         }
827         sqlite3_free(error_message);
828         return 0;
829 }