1df643e7716f975df14b1957f5e018d5d5890fce
[platform/core/appfw/ail.git] / tool / src / initdb.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 <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <dirent.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <errno.h>
32 #include <sys/smack.h>
33
34 #include "ail.h"
35 #include "ail_private.h"
36 #include "ail_db.h"
37
38 #ifdef _E
39 #undef _E
40 #endif
41 #define _E(fmt, arg...) fprintf(stderr, "[AIL_INITDB][E][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg)
42
43 #ifdef _D
44 #undef _D
45 #endif
46 #define _D(fmt, arg...) fprintf(stderr, "[AIL_INITDB][D][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg)
47
48 #define SET_DEFAULT_LABEL(x) \
49         do { \
50                 if (smack_setlabel((x), "*", SMACK_LABEL_ACCESS)) \
51                         _E("failed chsmack -a \"*\" %s", x); \
52                 else \
53                         _D("chsmack -a \"*\" %s", x); \
54         } while (0)
55
56 char *_desktop_to_package(const char* desktop)
57 {
58         char *package, *tmp;
59
60         retv_if(!desktop, NULL);
61
62         package = strdup(desktop);
63         retv_if(!package, NULL);
64
65         tmp = strrchr(package, '.');
66         if (tmp == NULL) {
67                 _E("[%s] is not a desktop file", package);
68                 free(package);
69                 return NULL;
70         }
71
72         if (strcmp(tmp, ".desktop")) {
73                 _E("%s is not a desktop file", desktop);
74                 free(package);
75                 return NULL;
76         }
77
78         *tmp = '\0';
79
80         return package;
81 }
82
83 int initdb_load_directory(const char *directory)
84 {
85         DIR *dir;
86         struct dirent entry, *result;
87         int ret;
88         char buf[BUFSZE];
89         int total_cnt = 0;
90         int ok_cnt = 0;
91
92         /* desktop file */
93         dir = opendir(directory);
94         if (!dir) {
95                 if (strerror_r(errno, buf, sizeof(buf)) == 0)
96                         _E("Failed to access the [%s] because %s\n", directory, buf);
97                 return AIL_ERROR_FAIL;
98         }
99
100         _D("Loading desktop files from %s", directory);
101
102         for (ret = readdir_r(dir, &entry, &result);
103                         ret == 0 && result != NULL;
104                         ret = readdir_r(dir, &entry, &result)) {
105                 char *package;
106
107                 if (entry.d_name[0] == '.') continue;
108                 total_cnt++;
109                 package = _desktop_to_package(entry.d_name);
110                 if (!package) {
111                         _E("Failed to convert file to package[%s]", entry.d_name);
112                         continue;
113                 }
114
115                 if (ail_desktop_add(package) != AIL_ERROR_OK)
116                         _E("Failed to add a package[%s]", package);
117                 else
118                         ok_cnt++;
119
120                 free(package);
121         }
122
123         _D("Application-Desktop process : Success [%d], fail[%d], total[%d] \n", ok_cnt, total_cnt-ok_cnt, total_cnt);
124         closedir(dir);
125
126         return AIL_ERROR_OK;
127 }
128
129 static int initdb_change_perm(const char *db_file)
130 {
131         char journal_file[BUFSZE];
132         char *files[3];
133         int ret, i;
134
135         files[0] = (char *)db_file;
136         files[1] = journal_file;
137         files[2] = NULL;
138
139         retv_if(!db_file, AIL_ERROR_FAIL);
140
141         snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
142
143         for (i = 0; files[i]; i++) {
144                 ret = chown(files[i], GLOBAL_USER, OWNER_ROOT);
145                 if (ret == -1) {
146                         _E("FAIL : chown %s %d.%d, because %d", db_file, OWNER_ROOT, OWNER_ROOT, errno);
147                         return AIL_ERROR_FAIL;
148                 }
149
150                 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
151                 if (ret == -1) {
152                         _E("FAIL : chmod %s 0664, because %d", db_file, errno);
153                         return AIL_ERROR_FAIL;
154                 }
155         }
156
157         return AIL_ERROR_OK;
158 }
159
160 static int __is_authorized()
161 {
162         /* ail_init db should be called by as root privilege. */
163         uid_t uid = getuid();
164         /* euid need to be root to allow smack label changes during initialization */
165         /* uid_t euid = geteuid(); */
166         if ((uid_t) OWNER_ROOT == uid)
167                 return 1;
168         else
169                 return 0;
170 }
171
172 int xsystem(const char *argv[])
173 {
174         int status = 0;
175         pid_t pid;
176         pid = fork();
177         switch (pid) {
178         case -1:
179                 perror("fork failed");
180                 return -1;
181         case 0:
182                 /* child */
183                 execvp(argv[0], (char *const *)argv);
184                 _exit(-1);
185         default:
186                 /* parent */
187                 break;
188         }
189         if (waitpid(pid, &status, 0) == -1) {
190                 perror("waitpid failed");
191                 return -1;
192         }
193         if (WIFSIGNALED(status)) {
194                 perror("signal");
195                 return -1;
196         }
197         if (!WIFEXITED(status)) {
198                 /* shouldn't happen */
199                 perror("should not happen");
200                 return -1;
201         }
202         return WEXITSTATUS(status);
203 }
204
205 int main(int argc, char *argv[])
206 {
207         int ret;
208
209         if (!__is_authorized()) {
210                 fprintf(stderr, "You are not an authorized user!\n");
211                 _D("You are not root user!\n");
212                 return -1;
213         } else {
214                 if (remove(APP_INFO_DB_FILE))
215                         _E(" %s is not removed", APP_INFO_DB_FILE);
216                 if (remove(APP_INFO_DB_FILE_JOURNAL))
217                         _E(" %s is not removed", APP_INFO_DB_FILE_JOURNAL);
218         }
219         ret = setenv("AIL_INITDB", "1", 1);
220         _D("AIL_INITDB : %d", ret);
221
222         if (setresuid(GLOBAL_USER, GLOBAL_USER, OWNER_ROOT) != 0)
223                 _E("setresuid() is failed.");
224
225         if (db_open(DB_OPEN_RW, GLOBAL_USER) != AIL_ERROR_OK) {
226                 _E("Fail to create system databases");
227                 return AIL_ERROR_DB_FAILED;
228         }
229         ret = initdb_load_directory(USR_DESKTOP_DIRECTORY);
230         if (ret == AIL_ERROR_FAIL)
231                 _E("cannot load usr desktop directory.");
232
233         if (setuid(OWNER_ROOT) != 0)
234                 _E("setuid() is failed.");
235
236         ret = initdb_change_perm(APP_INFO_DB_FILE);
237         if (ret == AIL_ERROR_FAIL)
238                 _E("cannot chown.");
239
240         SET_DEFAULT_LABEL(APP_INFO_DB_FILE);
241         SET_DEFAULT_LABEL(APP_INFO_DB_FILE_JOURNAL);
242
243         return AIL_ERROR_OK;
244 }