2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/types.h>
21 #include <sys/smack.h>
25 #include <pkgmgr_parser_db_queries.h>
26 #include <system_info.h>
29 #include <string_view>
31 #include "pkgmgrinfo_internal.h"
32 #include "pkgmgrinfo_private.h"
33 #include "pkgmgrinfo_debug.h"
37 constexpr const char DB_LABEL[] = "User::Home";
38 constexpr const char APPFW_USER[] = "app_fw";
39 constexpr const int OWNER_ROOT = 0;
40 constexpr const char DB_VERSION_PATH[] =
41 SYSCONFDIR "/package-manager/pkg_db_version.txt";
42 constexpr const char DB_VERSION_PATH_UNIT_TEST[] =
43 "./pkg_db_version.txt";
46 void SetSmackLabel(const char* x) {
47 if (smack_setlabel(x, DB_LABEL, SMACK_LABEL_ACCESS))
48 _LOGE("failed chsmack -a %s %s", DB_LABEL, x);
50 _LOGD("chsmack -a %s %s", DB_LABEL, x);
53 const char* GetVersionPath() {
55 return DB_VERSION_PATH_UNIT_TEST;
56 return DB_VERSION_PATH;
59 const char* GetCertDbPath() {
60 return tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
63 int SetDbPermission(const char* path, uid_t uid) {
66 char journal_file[BUFSIZE];
70 struct passwd *result;
75 if (getuid() != OWNER_ROOT)
78 if (uid == OWNER_ROOT || uid == GLOBAL_USER) {
79 ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
82 _LOGE("no such user: %d", uid);
84 _LOGE("getpwuid_r failed: %d", errno);
90 snprintf(journal_file, sizeof(journal_file), "%s-journal", path);
92 files[1] = journal_file;
94 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
97 _LOGE("no such user: %d", uid);
99 _LOGE("getpwuid_r failed: %d", errno);
103 for (i = 0; i < 2; i++) {
104 fd = open(files[i], O_RDONLY);
106 _LOGE("open %s failed: %d", files[i], errno);
109 ret = fstat(fd, &sb);
111 _LOGE("stat %s failed: %d", files[i], errno);
115 if (S_ISLNK(sb.st_mode)) {
116 _LOGE("%s is symlink!", files[i]);
120 ret = fchown(fd, uid, pwd.pw_gid);
122 _LOGE("fchown %s failed: %d", files[i], errno);
127 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
128 if (!strcmp(path, GetCertDbPath()))
130 ret = fchmod(fd, mode);
132 _LOGD("fchmod %s failed: %d", files[i], errno);
137 SetSmackLabel(files[i]);
143 int SetDbVersion(const tizen_base::Database& db) {
144 std::ifstream file(GetVersionPath(), std::fstream::in);
145 if (!static_cast<bool>(file)) {
146 _LOGE("Failed to open db version file: %s", GetVersionPath());
151 std::getline(file, version);
152 if (version.empty()) {
153 _LOGE("Failed to get version information");
157 std::string sql = "PRAGMA user_version=" + version;
159 db.OneStepExec({ sql });
160 } catch (const tizen_base::DbException& e) {
161 _LOGE("OneStepExec failed: %s", e.msg());
168 int CreateTables(const tizen_base::Database& db, const char** queries) {
170 for (int i = 0; queries[i] != nullptr; i++)
171 db.OneStepExec({ queries[i] });
172 } catch (const tizen_base::DbException& e) {
173 _LOGE("OneStepExec failed: %s", e.msg());
180 int InitDb(const tizen_base::Database& db, std::string_view dbpath,
182 const char** queries;
184 if (SetDbVersion(db))
187 if (dbpath.rfind(".pkgmgr_parser.db") != std::string::npos) {
188 queries = PARSER_INIT_QUERIES;
189 } else if (dbpath.rfind(".pkgmgr_cert.db") != std::string::npos) {
190 queries = CERT_INIT_QUERIES;
192 _LOGE("unexpected dbpath: %s", dbpath.data());
196 auto guard = db.CreateTransactionGuard();
198 if (CreateTables(db, queries) != 0)
202 if (SetDbPermission(dbpath.data(), uid))
203 _LOGE("failed to set db permission");
210 namespace pkgmgr_server::internal {
212 void SetEnableUnitTest(bool enable) {
216 int InitializeDb(const tizen_base::Database& db, uid_t uid) {
217 const char* dbpath = sqlite3_db_filename(db.GetRaw(), "main");
218 if (dbpath == nullptr) {
219 _LOGE("Fail to get db filename");
223 return InitDb(db, dbpath, uid);
226 } // namespace pkgmgr_server::internal