Remove package_app_app_svc
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_db.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <ctype.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <grp.h>
9 #include <dirent.h>
10 #include <libgen.h>
11
12 #include <sqlite3.h>
13
14 #include <tzplatform_config.h>
15 #include <db-util.h>
16
17 #include "pkgmgr-info.h"
18 #include "pkgmgrinfo_debug.h"
19 #include "pkgmgrinfo_private.h"
20 #include "pkgmgr_parser.h"
21 #include "pkgmgr_parser_internal.h"
22
23 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO "create table if not exists package_cert_index_info " \
24                                                 "(cert_info text not null, " \
25                                                 "cert_id integer, " \
26                                                 "cert_ref_count integer, " \
27                                                 "PRIMARY KEY(cert_id)) "
28
29 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INFO "create table if not exists package_cert_info " \
30                                                 "(package text not null, " \
31                                                 "author_root_cert integer, " \
32                                                 "author_im_cert integer, " \
33                                                 "author_signer_cert integer, " \
34                                                 "dist_root_cert integer, " \
35                                                 "dist_im_cert integer, " \
36                                                 "dist_signer_cert integer, " \
37                                                 "dist2_root_cert integer, " \
38                                                 "dist2_im_cert integer, " \
39                                                 "dist2_signer_cert integer, " \
40                                                 "PRIMARY KEY(package)) "
41 __thread db_handle manifest_db;
42 __thread db_handle cert_db;
43
44 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
45
46 static int _mkdir_for_user(const char* dir, uid_t uid, gid_t gid)
47 {
48         int ret;
49         char *fullpath;
50         char *subpath;
51
52         fullpath = strdup(dir);
53         if (fullpath == NULL)
54                 return -1;
55         subpath = dirname(fullpath);
56         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
57                 ret = _mkdir_for_user(fullpath, uid, gid);
58                 if (ret == -1) {
59                         free(fullpath);
60                         return ret;
61                 }
62         }
63
64         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
65         if (ret && errno != EEXIST) {
66                 free(fullpath);
67                 return ret;
68         } else if (ret && errno == EEXIST) {
69                 free(fullpath);
70                 return 0;
71         }
72
73         if (getuid() == ROOT_UID) {
74                 ret = chown(dir, uid, gid);
75                 if (ret == -1)
76                         _LOGE("FAIL : chown %s %d.%d, because %s", dir, uid,
77                                         gid, strerror(errno));
78         }
79
80         free(fullpath);
81
82         return 0;
83 }
84
85 static const char *_get_db_path(uid_t uid) {
86         const char *db_path = NULL;
87         if (uid != GLOBAL_USER && uid != ROOT_UID) {
88                 tzplatform_set_user(uid);
89                 db_path = tzplatform_getenv(TZ_USER_DB);
90                 tzplatform_reset_user();
91         } else {
92                 db_path = tzplatform_getenv(TZ_SYS_DB);
93         }
94         return db_path;
95 }
96
97 static int __attach_and_create_view(sqlite3 *handle, const char *db, const char *tables[], uid_t uid)
98 {
99         int i;
100         char *err;
101         char query[MAX_QUERY_LEN];
102
103         if (uid != GLOBAL_USER && uid != ROOT_UID) {
104                 snprintf(query, sizeof(query), "ATTACH DATABASE '%s' AS Global", db);
105                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
106                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
107                         sqlite3_free(err);
108                         return SQLITE_ERROR;
109                 }
110         }
111
112         for (i = 0; tables[i]; i++) {
113                 if (uid != GLOBAL_USER && uid != ROOT_UID)
114                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
115                                         FROM (SELECT *,0 AS for_all_users FROM main.'%s' UNION \
116                                         SELECT *,1 AS for_all_users FROM Global.'%s')",
117                                         tables[i], tables[i], tables[i]);
118                 else
119                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
120                                         FROM (SELECT *,1 AS for_all_users FROM main.'%s')",
121                                         tables[i], tables[i]);
122                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
123                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
124                         sqlite3_free(err);
125                 }
126         }
127
128         return SQLITE_OK;
129 }
130
131 static int __exec_db_query(sqlite3 *db, char *query, sqlite_query_callback callback, void *data)
132 {
133         char *error_message = NULL;
134         int ret = sqlite3_exec(db, query, callback, data, &error_message);
135         if (SQLITE_OK != ret) {
136                 _LOGE("Don't execute query = %s error message = %s   ret = %d\n", query,
137                        error_message, ret);
138                 sqlite3_free(error_message);
139                 return -1;
140         }
141         sqlite3_free(error_message);
142         return 0;
143 }
144
145 int _check_create_cert_db(sqlite3 *certdb)
146 {
147         int ret = 0;
148         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO, NULL, NULL);
149         if (ret < 0)
150                 return ret;
151         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INFO, NULL, NULL);
152         return ret;
153 }
154 static gid_t _get_gid(const char *name)
155 {
156         char buf[BUFSIZE];
157         struct group entry;
158         struct group *ge;
159         int ret;
160
161         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
162         if (ret || ge == NULL) {
163                 _LOGE("fail to get gid of %s", name);
164                 return -1;
165         }
166
167         return entry.gr_gid;
168 }
169
170 API const char *getIconPath(uid_t uid)
171 {
172         const char *path = NULL;
173         uid_t uid_caller = getuid();
174         gid_t gid = ROOT_UID;
175
176         if (uid != GLOBAL_USER && uid != ROOT_UID) {
177                 tzplatform_set_user(uid);
178                 path = tzplatform_mkpath(TZ_USER_ICONS, "/");
179                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
180                 tzplatform_reset_user();
181         } else {
182                 path = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
183         }
184
185         // just allow certain users to create the icon directory if needed.
186         if (uid_caller == ROOT_UID || uid_caller == uid)
187                 _mkdir_for_user(path, uid, gid);
188
189         return path;
190 }
191
192 API const char *getUserPkgParserDBPath(void)
193 {
194         return getUserPkgParserDBPathUID(GLOBAL_USER);
195 }
196
197 API const char *getUserPkgParserDBPathUID(uid_t uid)
198 {
199         const char *pkgmgr_parser_db = NULL;
200         uid_t uid_caller = getuid();
201         gid_t gid = ROOT_UID;
202
203         if (uid != GLOBAL_USER && uid != ROOT_UID) {
204                 tzplatform_set_user(uid);
205                 pkgmgr_parser_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db");
206                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
207                 tzplatform_reset_user();
208         } else {
209                 pkgmgr_parser_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
210         }
211
212         // just allow certain users to create the dbspace directory if needed.
213         if (uid_caller == ROOT_UID || uid_caller == uid) {
214                 const char *db_path = _get_db_path(uid);
215                 _mkdir_for_user(db_path, uid, gid);
216         }
217
218         return pkgmgr_parser_db;
219 }
220
221 API const char *getUserPkgCertDBPath(void)
222 {
223          return getUserPkgCertDBPathUID(GLOBAL_USER);
224 }
225
226 API const char *getUserPkgCertDBPathUID(uid_t uid)
227 {
228         const char *pkgmgr_cert_db = NULL;
229         uid_t uid_caller = getuid();
230         gid_t gid = ROOT_UID;
231
232         if (uid != GLOBAL_USER && uid != ROOT_UID) {
233                 tzplatform_set_user(uid);
234                 pkgmgr_cert_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_cert.db");
235                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
236                 tzplatform_reset_user();
237         } else {
238                 pkgmgr_cert_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
239         }
240
241         // just allow certain users to create the dbspace directory if needed.
242         if (uid_caller == ROOT_UID || uid_caller == uid) {
243                 const char *db_path = _get_db_path(uid);
244                 _mkdir_for_user(db_path, uid, gid);
245         }
246
247         return pkgmgr_cert_db;
248 }
249
250 API const char *getUserDesktopPath(uid_t uid)
251 {
252         const char *path = NULL;
253         uid_t uid_caller = getuid();
254         gid_t gid = ROOT_UID;
255
256         if (uid != GLOBAL_USER && uid != ROOT_UID) {
257                 tzplatform_set_user(uid);
258                 path = tzplatform_mkpath(TZ_USER_DESKTOP, "/");
259                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
260                 tzplatform_reset_user();
261         } else {
262                 path = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
263         }
264
265         // just allow certain users to create the icon directory if needed.
266         if (uid_caller == ROOT_UID || uid_caller == uid)
267                 _mkdir_for_user(path, uid, gid);
268
269         return path;
270 }
271
272 API const char *getUserManifestPath(uid_t uid)
273 {
274         const char *path = NULL;
275         uid_t uid_caller = getuid();
276         gid_t gid = ROOT_UID;
277
278         if (uid != GLOBAL_USER && uid != ROOT_UID) {
279                 tzplatform_set_user(uid);
280                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
281                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
282                 tzplatform_reset_user();
283         } else {
284                 path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
285         }
286
287         // just allow certain users to create the icon directory if needed.
288         if (uid_caller == ROOT_UID || uid_caller == uid)
289                 _mkdir_for_user(path, uid, gid);
290
291         return path;
292 }
293
294 int __close_manifest_db(void)
295 {
296         if (manifest_db.ref) {
297                 if (--manifest_db.ref == 0)
298                         sqlite3_close(GET_DB(manifest_db));
299                 return 0;
300         }
301         return -1;
302 }
303
304 static const char *parserdb_tables[] = {
305         "package_app_app_category",
306         "package_app_info",
307         "package_app_app_control",
308         "package_app_localized_info",
309         "package_app_app_metadata",
310         "package_app_share_allowed",
311         "package_app_app_permission",
312         "package_app_share_request",
313         "package_info",
314         "package_app_data_control",
315         "package_localized_info",
316         "package_app_icon_section_info",
317         "package_privilege_info",
318         "package_app_image_info",
319         NULL
320 };
321
322 int __open_manifest_db(uid_t uid, bool readonly)
323 {
324         int ret;
325         const char *user_pkg_parser;
326         int flags;
327
328         if (manifest_db.ref) {
329                 manifest_db.ref ++;
330                 return 0;
331         }
332
333         user_pkg_parser = getUserPkgParserDBPathUID(uid);
334         if (access(user_pkg_parser, F_OK) != 0) {
335                 _LOGE("Manifest DB does not exists !!");
336                 return -1;
337         }
338
339         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
340         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
341                         flags, NULL);
342         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!\n",
343                         user_pkg_parser);
344         manifest_db.ref++;
345         if (readonly) {
346                 ret = __attach_and_create_view(GET_DB(manifest_db), MANIFEST_DB,
347                                 parserdb_tables, uid);
348                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!\n",
349                                 user_pkg_parser);
350         }
351         return 0;
352 }
353
354 int __close_cert_db(void)
355 {
356         if (cert_db.ref) {
357                 if (--cert_db.ref == 0)
358                         sqlite3_close_v2(GET_DB(cert_db));
359                         return 0;
360         }
361         _LOGE("Certificate DB is already closed !!\n");
362         return -1;
363 }
364
365 static const char *certdb_tables[] = {
366         "package_cert_index_info",
367         "package_cert_info",
368         NULL
369 };
370
371 int __open_cert_db(uid_t uid, bool readonly)
372 {
373         int ret;
374         const char *user_cert_parser;
375         int flags;
376
377         if (cert_db.ref) {
378                 cert_db.ref ++;
379                 return 0;
380         }
381
382         user_cert_parser = getUserPkgCertDBPathUID(uid);
383         if (access(user_cert_parser, F_OK) != 0) {
384                 _LOGE("Cert DB does not exists !!");
385                 return -1;
386         }
387
388         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
389         ret = db_util_open_with_options(user_cert_parser, &GET_DB(cert_db),
390                         flags, NULL);
391         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!",
392                         user_cert_parser);
393         cert_db.ref++;
394         if (readonly) {
395                 ret = __attach_and_create_view(GET_DB(cert_db), CERT_DB,
396                                 certdb_tables, uid);
397                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!",
398                                 user_cert_parser);
399         }
400         return 0;
401 }
402
403 void _save_column_str(sqlite3_stmt *stmt, int idx, const char **str)
404 {
405         const char *val;
406
407         val = (const char *)sqlite3_column_text(stmt, idx);
408         if (val)
409                 *str = strdup(val);
410 }
411
412 API int pkgmgrinfo_pkginfo_set_state_enabled(const char *pkgid, bool enabled)
413 {
414         /* Should be implemented later */
415         return 0;
416 }
417
418 API int pkgmgrinfo_appinfo_set_usr_state_enabled(const char *appid, bool enabled, uid_t uid)
419 {
420         int ret;
421         char query[MAX_QUERY_LEN] = {'\0'};
422         char *error_message;
423
424         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
425
426         /* Open db.*/
427         ret = __open_manifest_db(uid, false);
428         if (ret != SQLITE_OK) {
429                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
430                 return PMINFO_R_ERROR;
431         }
432
433         /*Begin transaction*/
434         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
435         if (ret != SQLITE_OK) {
436                 _LOGE("Failed to begin transaction\n");
437                 __close_manifest_db();
438                 return PMINFO_R_ERROR;
439         }
440         _LOGD("Transaction Begin\n");
441
442         memset(query, '\0', MAX_QUERY_LEN);
443         snprintf(query, MAX_QUERY_LEN,
444                 "update package_app_info set app_enabled='%s' where app_id='%s'", enabled?"true":"false", appid);
445
446         if (SQLITE_OK !=
447             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
448                 _LOGE("Don't execute query = %s error message = %s\n", query,
449                        error_message);
450                 sqlite3_free(error_message);
451                 return PMINFO_R_ERROR;
452         }
453         sqlite3_free(error_message);
454
455         /*Commit transaction*/
456         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
457         if (ret != SQLITE_OK) {
458                 _LOGE("Failed to commit transaction. Rollback now\n");
459                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
460                 __close_manifest_db();
461                 return PMINFO_R_ERROR;
462         }
463         _LOGD("Transaction Commit and End\n");
464         __close_manifest_db();
465         return PMINFO_R_OK;
466 }
467
468 API int pkgmgrinfo_appinfo_set_state_enabled(const char *appid, bool enabled)
469 {
470         return pkgmgrinfo_appinfo_set_usr_state_enabled(appid, enabled, GLOBAL_USER);
471 }
472
473 API int pkgmgrinfo_appinfo_set_usr_default_label(const char *appid, const char *label, uid_t uid)
474 {
475         int ret;
476         char query[MAX_QUERY_LEN] = {'\0'};
477         char *error_message;
478
479         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
480
481         ret = __open_manifest_db(uid, false);
482         if (ret == -1) {
483                 _LOGE("Fail to open manifest DB\n");
484                 return PMINFO_R_ERROR;
485         }
486
487         /*Begin transaction*/
488         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
489         if (ret != SQLITE_OK) {
490                 _LOGE("Failed to begin transaction\n");
491                 __close_manifest_db();
492                 return PMINFO_R_ERROR;
493         }
494         _LOGD("Transaction Begin\n");
495
496         memset(query, '\0', MAX_QUERY_LEN);
497         snprintf(query, MAX_QUERY_LEN,
498                 "update package_app_localized_info set app_label='%s' where app_id='%s' and app_locale='No Locale'", label, appid);
499
500         if (SQLITE_OK !=
501             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
502                 _LOGE("Don't execute query = %s error message = %s\n", query,
503                        error_message);
504                 sqlite3_free(error_message);
505                 return PMINFO_R_ERROR;
506         }
507
508         /*Commit transaction*/
509         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
510         if (ret != SQLITE_OK) {
511                 _LOGE("Failed to commit transaction. Rollback now\n");
512                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
513                 __close_manifest_db();
514                 return PMINFO_R_ERROR;
515         }
516         _LOGD("Transaction Commit and End\n");
517         __close_manifest_db();
518         return PMINFO_R_OK;
519 }
520
521 API int pkgmgrinfo_appinfo_set_default_label(const char *appid, const char *label)
522 {
523         return pkgmgrinfo_appinfo_set_usr_default_label(appid, label, GLOBAL_USER);
524 }
525
526 API int pkgmgrinfo_appinfo_set_usr_guestmode_visibility(pkgmgrinfo_appinfo_h handle, uid_t uid, bool status)
527 {
528         const char *val;
529         int ret;
530         char query[MAX_QUERY_LEN] = {'\0'};
531         char *errmsg;
532         sqlite3 *pkgmgr_parser_db;
533
534         retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL\n");
535
536         pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
537         val = info->app_info->guestmode_visibility;
538         if (val) {
539                 ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
540                                 SQLITE_OPEN_READWRITE, NULL);
541                 if (ret != SQLITE_OK) {
542                         _LOGE("DB Open Failed\n");
543                         return PMINFO_R_ERROR;
544                 }
545
546                 /*TODO: Write to DB here*/
547                 if (status == true)
548                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'true' where app_id = '%s'", (char *)info->app_info->appid);
549                 else
550                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'false' where app_id = '%s'", (char *)info->app_info->appid);
551
552                 ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &errmsg);
553                 sqlite3_close(pkgmgr_parser_db);
554                 if (ret != SQLITE_OK) {
555                         _LOGE("DB update [%s] failed, error message = %s\n", query, errmsg);
556                         free(errmsg);
557                         return PMINFO_R_ERROR;
558                 }
559         }
560         return PMINFO_R_OK;
561 }
562
563 API int pkgmgrinfo_appinfo_set_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool status)
564 {
565         return pkgmgrinfo_appinfo_set_usr_guestmode_visibility(handle, GLOBAL_USER, status);
566 }