2 * security-manager, database access
4 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Rafal Krypa <r.krypa@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.
23 * @file privilege_db.cpp
24 * @author Krzysztof Sasiak <k.sasiak@samsung.com>
25 * @author Rafal Krypa <r.krypa@samsung.com>
27 * @brief This file contains declaration of the API to privileges database.
35 #include <dpl/log/log.h>
36 #include "privilege_db.h"
38 namespace SecurityManager {
40 /* Common code for handling SqlConnection exceptions */
42 T try_catch(const std::function<T()> &func)
46 } catch (DB::SqlConnection::Exception::SyntaxError &e) {
47 LogError("Syntax error in command: " << e.DumpToString());
48 ThrowMsg(PrivilegeDb::Exception::InternalError,
49 "Syntax error in command: " << e.DumpToString());
50 } catch (DB::SqlConnection::Exception::InternalError &e) {
51 LogError("Mysterious internal error in SqlConnection class" << e.DumpToString());
52 ThrowMsg(PrivilegeDb::Exception::InternalError,
53 "Mysterious internal error in SqlConnection class: " << e.DumpToString());
57 PrivilegeDb::PrivilegeDb(const std::string &path)
60 mSqlConnection = new DB::SqlConnection(path,
61 DB::SqlConnection::Flag::None,
62 DB::SqlConnection::Flag::RW);
64 } catch (DB::SqlConnection::Exception::Base &e) {
65 LogError("Database initialization error: " << e.DumpToString());
66 ThrowMsg(PrivilegeDb::Exception::IOError,
67 "Database initialization error:" << e.DumpToString());
72 void PrivilegeDb::initDataCommands()
74 for (auto &it : Queries) {
75 m_commands.push_back(mSqlConnection->PrepareDataCommand(it.second));
79 DB::SqlConnection::DataCommandAutoPtr & PrivilegeDb::getQuery(QueryType queryType)
81 auto &command = m_commands.at(static_cast<size_t>(queryType));
86 PrivilegeDb::~PrivilegeDb()
89 delete mSqlConnection;
92 PrivilegeDb &PrivilegeDb::getInstance()
94 static PrivilegeDb privilegeDb;
98 void PrivilegeDb::BeginTransaction(void)
100 try_catch<void>([&] {
101 mSqlConnection->BeginTransaction();
105 void PrivilegeDb::CommitTransaction(void)
107 try_catch<void>([&] {
108 mSqlConnection->CommitTransaction();
112 void PrivilegeDb::RollbackTransaction(void)
114 try_catch<void>([&] {
115 mSqlConnection->RollbackTransaction();
119 bool PrivilegeDb::PkgIdExists(const std::string &pkgId)
121 return try_catch<bool>([&] {
122 auto &command = getQuery(QueryType::EPkgIdExists);
123 command->BindString(1, pkgId.c_str());
124 return command->Step();
128 bool PrivilegeDb::GetAppPkgId(const std::string &appId, std::string &pkgId)
130 return try_catch<bool>([&] {
131 auto &command = getQuery(QueryType::EGetPkgId);
132 command->BindString(1, appId.c_str());
134 if (!command->Step()) {
135 // No application with such appId
139 // application package found in the database, get it
140 pkgId = command->GetColumnString(0);
146 void PrivilegeDb::AddApplication(const std::string &appId,
147 const std::string &pkgId, uid_t uid)
149 try_catch<void>([&] {
150 auto &command = getQuery(QueryType::EAddApplication);
151 command->BindString(1, appId.c_str());
152 command->BindString(2, pkgId.c_str());
153 command->BindInteger(3, static_cast<unsigned int>(uid));
155 if (command->Step()) {
156 LogDebug("Unexpected SQLITE_ROW answer to query: " <<
157 Queries.at(QueryType::EAddApplication));
160 LogDebug("Added appId: " << appId << ", pkgId: " << pkgId);
164 void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
167 try_catch<void>([&] {
169 if (!GetAppPkgId(appId, pkgId)) {
170 pkgIdIsNoMore = false;
174 auto &command = getQuery(QueryType::ERemoveApplication);
175 command->BindString(1, appId.c_str());
176 command->BindInteger(2, static_cast<unsigned int>(uid));
178 if (command->Step()) {
179 LogDebug("Unexpected SQLITE_ROW answer to query: " <<
180 Queries.at(QueryType::ERemoveApplication));
183 LogDebug("Removed appId: " << appId);
185 pkgIdIsNoMore = !(this->PkgIdExists(pkgId));
189 void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId, uid_t uid,
190 std::vector<std::string> ¤tPrivileges)
192 try_catch<void>([&] {
193 auto &command = getQuery(QueryType::EGetPkgPrivileges);
194 command->BindString(1, pkgId.c_str());
195 command->BindInteger(2, static_cast<unsigned int>(uid));
197 while (command->Step()) {
198 std::string privilege = command->GetColumnString(0);
199 LogDebug("Got privilege: " << privilege);
200 currentPrivileges.push_back(privilege);
205 void PrivilegeDb::GetAppPrivileges(const std::string &appId, uid_t uid,
206 std::vector<std::string> ¤tPrivileges)
208 try_catch<void>([&] {
209 DB::SqlConnection::DataCommandAutoPtr &command =
210 m_commands.at(static_cast<size_t>(QueryType::EGetAppPrivileges));
213 command->BindString(1, appId.c_str());
214 command->BindInteger(2, static_cast<unsigned int>(uid));
215 currentPrivileges.clear();
217 while (command->Step()) {
218 std::string privilege = command->GetColumnString(0);
219 LogDebug("Got privilege: " << privilege);
220 currentPrivileges.push_back(privilege);
225 void PrivilegeDb::RemoveAppPrivileges(const std::string &appId, uid_t uid)
227 try_catch<void>([&] {
228 auto &command = getQuery(QueryType::ERemoveAppPrivileges);
229 command->BindString(1, appId.c_str());
230 command->BindInteger(2, static_cast<unsigned int>(uid));
231 if (command->Step()) {
232 LogDebug("Unexpected SQLITE_ROW answer to query: " <<
233 Queries.at(QueryType::ERemoveAppPrivileges));
236 LogDebug("Removed all privileges for appId: " << appId);
240 void PrivilegeDb::UpdateAppPrivileges(const std::string &appId, uid_t uid,
241 const std::vector<std::string> &privileges)
243 try_catch<void>([&] {
244 auto &command = getQuery(QueryType::EAddAppPrivileges);
245 command->BindString(1, appId.c_str());
246 command->BindInteger(2, static_cast<unsigned int>(uid));
248 RemoveAppPrivileges(appId, uid);
250 for (const auto &privilege : privileges) {
251 command->BindString(3, privilege.c_str());
254 LogDebug("Added privilege: " << privilege << " to appId: " << appId);
259 void PrivilegeDb::GetPrivilegeGroups(const std::string &privilege,
260 std::vector<std::string> &groups)
262 try_catch<void>([&] {
263 auto &command = getQuery(QueryType::EGetPrivilegeGroups);
264 command->BindString(1, privilege.c_str());
266 while (command->Step()) {
267 std::string groupName = command->GetColumnString(0);
268 LogDebug("Privilege " << privilege << " gives access to group: " << groupName);
269 groups.push_back(groupName);
274 void PrivilegeDb::GetUserApps(uid_t uid, std::vector<std::string> &apps)
276 try_catch<void>([&] {
277 auto &command = getQuery(QueryType::EGetUserApps);
278 command->BindInteger(1, static_cast<unsigned int>(uid));
280 while (command->Step()) {
281 std::string app = command->GetColumnString(0);
282 LogDebug("User " << uid << " has app " << app << " installed");
288 void PrivilegeDb::GetAppIdsForPkgId(const std::string &pkgId,
289 std::vector<std::string> &appIds)
291 try_catch<void>([&] {
292 DB::SqlConnection::DataCommandAutoPtr &command =
293 m_commands.at(static_cast<size_t>(QueryType::EGetAppsInPkg));
296 command->BindString(1, pkgId.c_str());
299 while (command->Step()) {
300 std::string appId = command->GetColumnString (0);
301 LogDebug ("Got appid: " << appId << " for pkgId " << pkgId);
302 appIds.push_back(appId);
307 } //namespace SecurityManager