uid INTEGER NOT NULL,
privilege VARCHAR NOT NULL,
type INTEGER NOT NULL CHECK (type >= 0 AND type <= 1),
+license VARCHAR,
FOREIGN KEY (app_id, uid) REFERENCES user_app (app_id, uid) ON UPDATE CASCADE ON DELETE CASCADE
);
+-- TODO CREATE INDEX + performance tests required
+-- CREATE INDEX IF NOT EXISTS app_defined_privilege_index ON app_defined_privilege (app_id, uid);
+
+-- This table contains privilege name that is also stored in
+-- app_defined_privilege table.
+-- It's time to consider using INTEGER instead VARCHAR and store
+-- all names of privilege in new table (We will skip this in POC).
+CREATE TABLE IF NOT EXISTS client_license (
+app_id INTEGER NOT NULL,
+uid INTEGER NOT NULL,
+privilege VARCHAR NOT NULL,
+license VARCHAR NOT NULL,
+FOREIGN KEY(app_id, uid) REFERENCES user_app (app_id, uid) ON UPDATE CASCADE ON DELETE CASCADE
+);
+
+-- TODO CREATE INDEX + performance tests required
+-- CREATE INDEX IF NOT EXISTS client_license_index ON client_license (app_id, uid);
+
DROP VIEW IF EXISTS user_app_pkg_view;
CREATE VIEW user_app_pkg_view AS
SELECT
name AS app_name,
uid,
privilege,
- type
+ type,
+ license
FROM app_defined_privilege
-LEFT JOIN app USING (app_id)
-LEFT JOIN user_app USING (app_id, uid);
+LEFT JOIN app USING (app_id);
DROP TRIGGER IF EXISTS app_defined_privilege_view_insert_trigger;
CREATE TRIGGER app_defined_privilege_view_insert_trigger
WHERE NOT EXISTS (SELECT 1 FROM user_app_pkg_view
WHERE uid=NEW.uid AND app_name=NEW.app_name);
- INSERT OR IGNORE INTO app_defined_privilege (app_id, uid, privilege, type)
- VALUES ((SELECT app_id FROM app WHERE name=NEW.app_name), NEW.uid, NEW.privilege, NEW.type);
+ INSERT OR IGNORE INTO app_defined_privilege (app_id, uid, privilege, type, license)
+ VALUES ((SELECT app_id FROM app WHERE name=NEW.app_name), NEW.uid, NEW.privilege, NEW.type, NEW.license);
END;
DROP TRIGGER IF EXISTS app_defined_privilege_view_delete_trigger;
WHERE app_id=(SELECT app_id FROM app WHERE name=OLD.app_name) AND uid=OLD.uid;
END;
+DROP VIEW IF EXISTS client_license_view;
+CREATE VIEW client_license_view AS
+SELECT
+ name AS app_name,
+ uid,
+ privilege,
+ license
+FROM client_license
+LEFT JOIN app USING (app_id);
+
+DROP TRIGGER IF EXISTS client_license_view_insert_trigger;
+CREATE TRIGGER client_license_view_insert_trigger
+INSTEAD OF INSERT ON client_license_view
+BEGIN
+ SELECT RAISE(ABORT, 'Application was not found')
+ WHERE NOT EXISTS (SELECT 1 FROM user_app_pkg_view
+ WHERE uid=NEW.uid AND app_name=NEW.app_name);
+
+ INSERT OR IGNORE INTO client_license (app_id, uid, privilege, license)
+ VALUES ((SELECT app_id FROM app WHERE name=NEW.app_name), NEW.uid, NEW.privilege, NEW.license);
+END;
+
+DROP TRIGGER IF EXISTS client_license_view_delete_trigger;
+CREATE TRIGGER client_license_view_delete_trigger
+INSTEAD OF DELETE ON client_license_view
+BEGIN
+ DELETE FROM client_license
+ WHERE app_id=(SELECT app_id FROM app WHERE name=OLD.app_name) AND uid=OLD.uid;
+END;
+
COMMIT TRANSACTION;
*/
#include <iostream>
+#include <cxxabi.h>
#include <fcntl.h>
#include <poll.h>
{
try {
return func();
+ } catch (abi::__forced_unwind &) {
+ throw;
} catch (const Exception &e) {
LogError("SecurityManager::Exception " << e.DumpToString());
std::cerr << "SecurityManager::Exception " << e.DumpToString() << std::endl;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ std::cerr << "Memory allocation failed: " << e.what() << std::endl;
+ return SECURITY_MANAGER_ERROR_MEMORY;
} catch (const std::exception &e) {
LogError("STD exception " << e.what());
std::cerr << "STD exception " << e.what() << std::endl;
#include <utility>
#include <atomic>
#include <stdlib.h>
+#include <cxxabi.h>
#include <unistd.h>
#include <grp.h>
SECURITY_MANAGER_API
int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
{
- if (!p_req || !privilege)
- return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ return security_manager_app_inst_req_add_client_privilege(p_req, privilege, nullptr);
+}
- p_req->privileges.push_back(privilege);
+SECURITY_MANAGER_API
+int security_manager_app_inst_req_add_client_privilege(app_inst_req *p_req, const char *privilege, const char *license)
+{
+ return try_catch([&]() -> int {
+ if (!p_req || !privilege)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
- return SECURITY_MANAGER_SUCCESS;
+ p_req->privileges.push_back(std::make_pair(
+ std::string(privilege),
+ license ? std::string(license) : std::string()));
+
+ return SECURITY_MANAGER_SUCCESS;
+ });
}
SECURITY_MANAGER_API
app_inst_req *p_req,
const char *app_defined_privilege,
const app_defined_privilege_type type,
- const char *)
+ const char *license)
{
if (!p_req || !app_defined_privilege ||
- type < SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED || type > SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED)
+ type < SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED || type > SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED ||
+ (type == SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED && !license))
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
- p_req->appDefinedPrivileges.push_back(std::make_pair(app_defined_privilege, static_cast<int>(type)));
+ p_req->appDefinedPrivileges.push_back(std::make_tuple(app_defined_privilege, static_cast<int>(type), license));
return SECURITY_MANAGER_SUCCESS;
}
}
SECURITY_MANAGER_API
-int security_manager_identify_privilege_provider(const char *privilege, uid_t uid,
- char **pkg_name, char **app_name)
+int security_manager_get_app_defined_privilege_provider(
+ const char *privilege,
+ uid_t uid,
+ char **pkg_name,
+ char **app_name)
{
using namespace SecurityManager;
return try_catch([&]() -> int {
LogDebug(__PRETTY_FUNCTION__ << " called");
+ if (privilege == NULL) {
+ LogError("privilege could not be NULL");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
if (pkg_name == NULL && app_name == NULL) {
LogError("Both pkg_name and app_name are NULL");
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
}
- ClientRequest request(SecurityModuleCall::GET_PRIVILEGE_PROVIDER);
- if (request.send(std::string(privilege), uid).failed())
+ ClientRequest request(SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER);
+ if (request.send(uid, std::string(privilege)).failed())
return request.getStatus();
- std::pair<std::string, std::string> provider;
- request.recv(provider);
- std::string appNameString = provider.first;
- std::string pkgNameString = provider.second;
+ std::string appNameString;
+ std::string pkgNameString;
+ request.recv(appNameString, pkgNameString);
if (appNameString.empty() || pkgNameString.empty()) {
LogError("Unexpected empty appName or pkgName");
return SECURITY_MANAGER_SUCCESS;
});
-}
\ No newline at end of file
+}
+
+SECURITY_MANAGER_API
+int security_manager_get_app_defined_privilege_license(
+ const char *privilege,
+ uid_t uid,
+ char **license)
+{
+ using namespace SecurityManager;
+ return try_catch([&]() -> int {
+ LogDebug(__PRETTY_FUNCTION__ << " called");
+
+ if (privilege == NULL || license == NULL) {
+ LogError("privilege, license could not be NULL");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
+ ClientRequest request(SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE);
+ if (request.send(uid, std::string(privilege)).failed())
+ return request.getStatus();
+
+ std::string licenseString;
+ request.recv(licenseString);
+
+ if (!(*license = strdup(licenseString.c_str()))) {
+ LogError("Memory allocation in strdup failed.");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
+
+SECURITY_MANAGER_API
+int security_manager_get_client_privilege_license(
+ const char *privilege,
+ const char *app_name,
+ uid_t uid,
+ char **license)
+{
+ return try_catch([&]() -> int {
+ using namespace SecurityManager;
+ LogDebug(__PRETTY_FUNCTION__ << " called");
+
+ if (privilege == NULL || app_name == NULL || license == NULL) {
+ LogError("privilege, app_name, license could not be NULL");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
+ ClientRequest request(SecurityModuleCall::GET_CLIENT_PRIVILEGE_LICENSE);
+ if (request.send(std::string(app_name), uid, std::string(privilege)).failed())
+ return request.getStatus();
+
+ std::string licenseString;
+ request.recv(licenseString);
+
+ if (!(*license = strdup(licenseString.c_str()))) {
+ LogError("Memory allocation in strdup failed.");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
}
}
if (vm.count("privilege")) {
- req.privileges = vm["privilege"].as<std::vector<std::string> >();
+ auto privVector = vm["privilege"].as<std::vector<std::string > >();
+ for (auto &e : privVector)
+ req.privileges.push_back(std::make_pair(e, std::string()));
+
if (req.privileges.empty()) {
po::error e("Error in parsing privilege arguments.");
throw e;
#ifdef BUILD_TYPE_DEBUG
LogDebug("Passed privileges:");
for (const auto &p : req.privileges) {
- LogDebug(" " << p);
+ LogDebug(" " << p.first);
}
#endif
}
bool global,
uid_t uid,
const std::vector<std::string> &privileges,
- const std::vector<std::pair<std::string, int>> &oldAppDefinedPrivileges,
- const std::vector<std::pair<std::string, int>> &newAppDefinedPrivileges,
+ const AppDefinedPrivilegesVector &oldAppDefinedPrivileges,
+ const AppDefinedPrivilegesVector &newAppDefinedPrivileges,
bool policyRemove)
{
std::vector<CynaraAdminPolicy> oldPolicies;
std::vector<CynaraAdminPolicy> oldUntrustedPolicies;
std::vector<CynaraAdminPolicy> oldLicensedPolicies;
- for (const std::pair<std::string, int> &p : oldAppDefinedPrivileges) {
- switch (p.second) {
+ for (const AppDefinedPrivilege &p : oldAppDefinedPrivileges) {
+ switch (std::get<1>(p)) {
case SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED:
listPolicies(Buckets.at(Bucket::APPDEFINED), CYNARA_ADMIN_WILDCARD, cynaraUser,
- p.first, oldUntrustedPolicies);
+ std::get<0>(p), oldUntrustedPolicies);
break;
case SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED:
listPolicies(Buckets.at(Bucket::APPDEFINED), CYNARA_ADMIN_WILDCARD, cynaraUser,
- p.first, oldLicensedPolicies);
+ std::get<0>(p), oldLicensedPolicies);
break;
}
}
- for (const std::pair<std::string, int> &p : newAppDefinedPrivileges) {
- switch (p.second) {
+ for (const AppDefinedPrivilege &p : newAppDefinedPrivileges) {
+ switch (std::get<1>(p)) {
case SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED:
- untrustedPrivileges.push_back(p.first);
+ untrustedPrivileges.push_back(std::get<0>(p));
break;
case SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED:
- licensedPrivileges.push_back(p.first);
+ licensedPrivileges.push_back(std::get<0>(p));
break;
}
}
#include <sys/eventfd.h>
#include "security-manager.h"
+#include "privilege_db.h"
namespace SecurityManager {
*/
void updateAppPolicy(const std::string &label, bool global, uid_t uid,
const std::vector<std::string> &privileges,
- const std::vector<std::pair<std::string, int>> &oldAppDefinedPrivileges,
- const std::vector<std::pair<std::string, int>> &newAppDefinedPrivileges,
+ const AppDefinedPrivilegesVector &oldAppDefinedPrivileges,
+ const AppDefinedPrivilegesVector &newAppDefinedPrivileges,
bool policyRemove = false);
/**
EIsPackageHybrid,
EGetPackagesInfo,
EAddAppDefinedPrivilege,
+ EAddClientPrivilege,
ERemoveAppDefinedPrivileges,
+ ERemoveClientPrivileges,
EGetAppDefinedPrivileges,
- EGetAppForAppDefinedPrivilege,
+ EGetAppAndLicenseForAppDefinedPrivilege,
+ EGetLicenseForClientPrivilege,
+ EIsUserAppInstalled,
};
-typedef std::pair<std::string, int> Privilege;
-typedef std::vector<Privilege> PrivilegesVector;
+// privilege, app_defined_privilege_type, license
+typedef std::tuple<std::string, int, std::string> AppDefinedPrivilege;
+typedef std::vector<AppDefinedPrivilege> AppDefinedPrivilegesVector;
class PrivilegeDb {
/**
{ StmtType::EIsPackageSharedRO, "SELECT shared_ro FROM pkg WHERE name=?"},
{ StmtType::EIsPackageHybrid, "SELECT is_hybrid FROM pkg WHERE name=?"},
{ StmtType::EGetPackagesInfo, "SELECT name, shared_ro, is_hybrid FROM pkg"},
- { StmtType::EAddAppDefinedPrivilege, "INSERT INTO app_defined_privilege_view (app_name, uid, privilege, type) VALUES (?, ?, ?, ?)"},
+ { StmtType::EAddAppDefinedPrivilege, "INSERT INTO app_defined_privilege_view (app_name, uid, privilege, type, license) VALUES (?, ?, ?, ?, ?)"},
+ { StmtType::EAddClientPrivilege, "INSERT INTO client_license_view (app_name, uid, privilege, license) VALUES (?, ?, ?, ?)"},
{ StmtType::ERemoveAppDefinedPrivileges, "DELETE FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
- { StmtType::EGetAppDefinedPrivileges, "SELECT privilege, type FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
- { StmtType::EGetAppForAppDefinedPrivilege, "SELECT app_name FROM app_defined_privilege_view WHERE privilege = ? AND uid = ?"},
+ { StmtType::ERemoveClientPrivileges, "DELETE FROM client_license_view WHERE app_name = ? AND uid = ?"},
+ { StmtType::EGetAppDefinedPrivileges, "SELECT privilege, type, license FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
+ { StmtType::EGetAppAndLicenseForAppDefinedPrivilege, "SELECT app_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?"},
+ { StmtType::EGetLicenseForClientPrivilege, "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? "},
+ { StmtType::EIsUserAppInstalled, "SELECT count(*) FROM user_app_pkg_view WHERE app_name = ? AND uid = ?"},
};
/**
void GetPackagesInfo(std::vector<PkgInfo> &packages);
/**
- * Add new privilege defined by application
+ * Add new privilege and license defined by application
*
* @param[in] appName - application identifier
* @param[in] uid - user identifier
* @exception PrivilegeDb::Exception::InternalError on internal error
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
- void AddAppDefinedPrivilege(const std::string &appName, uid_t uid, const Privilege &privilege);
+ void AddAppDefinedPrivilege(const std::string &appName, uid_t uid, const AppDefinedPrivilege &privilege);
/**
* Add vector of privileges defined by application
* @exception PrivilegeDb::Exception::InternalError on internal error
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
- void AddAppDefinedPrivileges(const std::string &appName, uid_t uid, const PrivilegesVector &privileges);
+ void AddAppDefinedPrivileges(const std::string &appName, uid_t uid, const AppDefinedPrivilegesVector &privileges);
/**
- * Remove privileges defined by application
+ * Add privilege and license used by client application
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ * @param[in] privilege - privilege identifier
+ * @param[in] license - license
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void AddClientPrivilege(const std::string &appName, uid_t uid, const std::string &privilege,
+ const std::string &license);
+
+ /**
+ * Remove privileges/licenses defined by application
*
* @param[in] appName - application identifier
* @param[in] uid - user identifier
*/
void RemoveAppDefinedPrivileges(const std::string &appName, uid_t uid);
+ /**
+ * Remove privileges/licenses used by client application
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void RemoveClientPrivileges(const std::string &appName, uid_t uid);
+
/**
* Retrieve vector of pairs with privilege (1st value) and privilege type (2nd value)
*
* @exception PrivilegeDb::Exception::InternalError on internal error
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
- void GetAppDefinedPrivileges(const std::string &appName, uid_t uid, PrivilegesVector &privileges);
+ void GetAppDefinedPrivileges(const std::string &appName, uid_t uid, AppDefinedPrivilegesVector &privileges);
/**
- * Retrieve application which define privilege
+ * Retrieve application and license of application which define privilege
*
- * @param[in] privilege - privilege identifier
* @param[in] uid - user identifier
+ * @param[in] privilege - privilege identifier
* @param[out] appName - application identifier
+ * @param[out] license - verification factor required by license-manager
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void GetAppAndLicenseForAppDefinedPrivilege(uid_t uid, const std::string &privilege,
+ std::string &appName, std::string &license);
+
+ /**
+ * Retrieve license of client application
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ * @param[in] privilege - privilege identifier
+ * @param[out] license - verification factor required by license-manager
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void GetLicenseForClientPrivilege(const std::string &appName, uid_t uid, const std::string &privilege,
+ std::string &license);
+
+ /**
+ * Check whether user has installed application
*
* @exception PrivilegeDb::Exception::InternalError on internal error
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
- void GetAppForAppDefinedPrivilege(const Privilege &privilege, uid_t uid, std::string &appName);
+ bool IsUserAppInstalled(const std::string& appName, uid_t uid);
};
} //namespace SecurityManager
struct app_inst_req {
std::string appName;
std::string pkgName;
- std::vector<std::string> privileges;
- std::vector<std::pair<std::string, int>> appDefinedPrivileges;
+ std::vector<std::pair<std::string, std::string>> privileges;
+ std::vector<std::tuple<std::string, int, std::string>> appDefinedPrivileges;
pkg_paths pkgPaths;
uid_t uid;
std::string tizenVersion;
GROUPS_FOR_UID,
LABEL_FOR_PROCESS,
SHM_APP_NAME,
- GET_PRIVILEGE_PROVIDER,
+ GET_APP_DEFINED_PRIVILEGE_PROVIDER,
+ GET_APP_DEFINED_PRIVILEGE_LICENSE,
+ GET_CLIENT_PRIVILEGE_LICENSE,
NOOP = 0x90,
};
/**
* Retrieves the app_id/pkg_id associated with given privilege and uid.
*
+ * @param[in] uid user identifier
+ * @param[in] privilege privilege name
+ * @param[out] appName returns app_id
+ * @param[out] pkgName returns pkg_id
+ *
+ * @return API return code, as defined in protocols.h
+ */
+ int getAppDefinedPrivilegeProvider(uid_t uid, const std::string &privilege,
+ std::string &appName, std::string &pkgName);
+
+ /**
+ * Retrieves the license associated with given privilege and uid.
+ *
+ * @param[in] uid user identifier
* @param[in] privilege privilege name
+ * @param[out] license returns license information connected with privilege
+ *
+ * @return API return code, as defined in protocols.h
+ */
+ int getAppDefinedPrivilegeLicense(uid_t uid, const std::string &privilege,
+ std::string &license);
+
+ /**
+ * Retrieves the license associated with given privilege and uid.
+ *
+ * @param[in] appName application identifier
* @param[in] uid user identifier
- * @param[out] provider returned pair of app_id and pkg_id
+ * @param[in] privilege privilege name
+ * @param[out] license returns license information connected with privilege
*
* @return API return code, as defined in protocols.h
*/
- int getPrivilegeProvider(const std::string &privilege, uid_t uid,
- std::pair<std::string, std::string> &provider);
+ int getClientPrivilegeLicense(const std::string &appName, uid_t uid,
+ const std::string &privilege,
+ std::string &license);
private:
bool authenticate(const Credentials &creds, const std::string &privilege);
});
}
-void PrivilegeDb::AddAppDefinedPrivilege(const std::string &appName, uid_t uid, const Privilege &privilege)
+void PrivilegeDb::AddAppDefinedPrivilege(const std::string &appName, uid_t uid,
+ const AppDefinedPrivilege &privilege)
{
try_catch<void>([&] {
auto command = getStatement(StmtType::EAddAppDefinedPrivilege);
command->BindString(1, appName);
command->BindInteger(2, uid);
- command->BindString(3, privilege.first);
- command->BindInteger(4, privilege.second);
+ command->BindString(3, std::get<0>(privilege));
+ command->BindInteger(4, std::get<1>(privilege));
+ command->BindString(5, std::get<2>(privilege));
- if (command->Step())
- LogDebug("Added privilege: " << privilege.first << " defined by: " << appName <<
- " and user: " << uid);
+ if (command->Step()) {
+ LogDebug("Unexpected SQLITE_ROW answer to query: " <<
+ Queries.at(StmtType::EAddAppDefinedPrivilege));
+ }
+
+ LogDebug("Added privilege: " << std::get<0>(privilege) << " defined by: " << appName <<
+ " and user: " << uid);
});
}
-void PrivilegeDb::AddAppDefinedPrivileges(const std::string &appName, uid_t uid, const PrivilegesVector &privileges)
+void PrivilegeDb::AddAppDefinedPrivileges(const std::string &appName, uid_t uid,
+ const AppDefinedPrivilegesVector &privileges)
{
for (const auto &privilege : privileges)
AddAppDefinedPrivilege(appName, uid, privilege);
}
+void PrivilegeDb::AddClientPrivilege(const std::string &appName, uid_t uid, const std::string &privilege,
+ const std::string &license)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::EAddClientPrivilege);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+ command->BindString(3, privilege);
+ command->BindString(4, license);
+
+ if (command->Step()) {
+ LogDebug("Unexpected SQLITE_ROW answer to query: " <<
+ Queries.at(StmtType::EAddClientPrivilege));
+ }
+
+ LogDebug("Added privilege: " << privilege << " license: " << license <<
+ "defined by: " << appName << " and user: " << uid);
+ });
+}
+
void PrivilegeDb::RemoveAppDefinedPrivileges(const std::string &appName, uid_t uid)
{
try_catch<void>([&] {
command->BindString(1, appName);
command->BindInteger(2, uid);
- if (command->Step())
- LogDebug("Removed privileges defined by: " << appName << " and user: " << uid);
+ if (command->Step()) {
+ LogDebug("Unexpected SQLITE_ROW answer to query: " <<
+ Queries.at(StmtType::ERemoveAppDefinedPrivileges));
+ };
+
+ LogDebug("Removed privileges defined by: " << appName << " and user: " << uid);
+ });
+}
+
+void PrivilegeDb::RemoveClientPrivileges(const std::string &appName, uid_t uid)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::ERemoveClientPrivileges);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+
+ if (command->Step()) {
+ LogDebug("Unexpected SQLITE_ROW answer to query: " <<
+ Queries.at(StmtType::ERemoveClientPrivileges));
+ };
+
+ LogDebug("Removed privileges used by: " << appName << " and user: " << uid);
});
}
-void PrivilegeDb::GetAppDefinedPrivileges(const std::string &appName, uid_t uid, PrivilegesVector &privileges)
+void PrivilegeDb::GetAppDefinedPrivileges(const std::string &appName, uid_t uid,
+ AppDefinedPrivilegesVector &privileges)
{
try_catch<void>([&] {
privileges.clear();
while (command->Step()) {
auto privilege = command->GetColumnString(0);
auto type = command->GetColumnInteger(1);
+ auto license = command->GetColumnString(2);
LogDebug("App: " << appName << " installed by: " << uid << " defines privilege: " << privilege);
- privileges.push_back(std::make_pair(privilege, type));
+ privileges.push_back(std::make_tuple<>(privilege, type, license));
}
});
}
-void PrivilegeDb::GetAppForAppDefinedPrivilege(const Privilege &privilege, uid_t uid, std::string &appName)
+void PrivilegeDb::GetAppAndLicenseForAppDefinedPrivilege(uid_t uid, const std::string &privilege,
+ std::string &appName, std::string &license)
{
try_catch<void>([&] {
appName.clear();
+ license.clear();
- auto command = getStatement(StmtType::EGetAppForAppDefinedPrivilege);
- command->BindString(1, privilege.first);
- command->BindInteger(2, uid);
+ auto command = getStatement(StmtType::EGetAppAndLicenseForAppDefinedPrivilege);
+ command->BindInteger(1, uid);
+ command->BindString(2, privilege);
- if (command->Step())
+ if (command->Step()) {
appName = command->GetColumnString(0);
+ license = command->GetColumnString(1);
+ }
if (!appName.empty())
- LogDebug("Privilege: " << privilege.first << " defined by " << appName);
+ LogDebug("Privilege: " << privilege << " defined by " << appName);
+ else
+ LogDebug("Privilege: " << privilege << " not exist");
+ });
+}
+
+void PrivilegeDb::GetLicenseForClientPrivilege(const std::string &appName, uid_t uid,
+ const std::string &privilege, std::string &license)
+{
+ try_catch<void>([&] {
+ license.clear();
+
+ auto command = getStatement(StmtType::EGetLicenseForClientPrivilege);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+ command->BindString(3, privilege);
+
+ if (command->Step())
+ license = command->GetColumnString(0);
+
+ if (license.empty())
+ LogDebug("License not found for app: " << appName << " privilege: " << privilege << " uid: " << uid);
else
- LogDebug("Privilege: " << privilege.first << " not exist");
+ LogDebug("License found for app: " << appName << " privilege: " << privilege << " uid: " << uid << " License: " << license);
+ });
+}
+
+bool PrivilegeDb::IsUserAppInstalled(const std::string& appName, uid_t uid)
+{
+ return try_catch<bool>([&]() -> bool {
+ auto command = getStatement(StmtType::EIsUserAppInstalled);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+ int isInstalled = 0;
+
+ if (command->Step())
+ isInstalled = command->GetColumnInteger(0);
+
+ return (isInstalled > 0);
});
}
/*
- * Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
bool hasSharedRO = isSharedRO(req.pkgPaths);
try {
+ std::vector<std::string> privilegeList;
+ privilegeList.reserve(req.privileges.size());
+
+ for (auto &e : req.privileges)
+ privilegeList.push_back(e.first);
+
setRequestDefaultValues(req.uid, req.installationType);
LogDebug("Install parameters: appName: " << req.appName << ", pkgName: " << req.pkgName
getPkgLabels(req.pkgName, pkgLabels);
m_privilegeDb.GetPkgAuthorId(req.pkgName, authorId);
- PrivilegesVector oldAppDefinedPrivileges;
+ AppDefinedPrivilegesVector oldAppDefinedPrivileges;
m_privilegeDb.GetAppDefinedPrivileges(req.appName, req.uid, oldAppDefinedPrivileges);
bool global = req.installationType == SM_APP_INSTALL_GLOBAL ||
req.installationType == SM_APP_INSTALL_PRELOADED;
- m_cynaraAdmin.updateAppPolicy(appLabel, global, req.uid, req.privileges,
+ m_cynaraAdmin.updateAppPolicy(appLabel, global, req.uid, privilegeList,
oldAppDefinedPrivileges, req.appDefinedPrivileges);
m_privilegeDb.RemoveAppDefinedPrivileges(req.appName, req.uid);
m_privilegeDb.AddAppDefinedPrivileges(req.appName, req.uid, req.appDefinedPrivileges);
+ m_privilegeDb.RemoveClientPrivileges(req.appName, req.uid);
+ for (auto &e : req.privileges) {
+ if (!e.second.empty())
+ m_privilegeDb.AddClientPrivilege(req.appName, req.uid, e.first, e.second);
+ }
+
if (hasSharedRO)
m_privilegeDb.SetSharedROPackage(req.pkgName);
}
}
- PrivilegesVector oldAppDefinedPrivileges;
+ AppDefinedPrivilegesVector oldAppDefinedPrivileges;
m_privilegeDb.GetAppDefinedPrivileges(req.appName, req.uid, oldAppDefinedPrivileges);
m_privilegeDb.RemoveApplication(req.appName, req.uid, removeApp, removePkg, removeAuthor);
bool global = req.installationType == SM_APP_INSTALL_GLOBAL ||
req.installationType == SM_APP_INSTALL_PRELOADED;
m_cynaraAdmin.updateAppPolicy(processLabel, global, req.uid, std::vector<std::string>(),
- oldAppDefinedPrivileges, std::vector<std::pair<std::string, int>>(), true);
+ oldAppDefinedPrivileges, AppDefinedPrivilegesVector(), true);
trans.commit();
LogDebug("Application uninstallation commited to database");
return SECURITY_MANAGER_SUCCESS;
}
-int ServiceImpl::getPrivilegeProvider(const std::string &privilege, uid_t uid,
- std::pair<std::string, std::string> &provider)
+int ServiceImpl::getAppDefinedPrivilegeProvider(uid_t uid, const std::string &privilege,
+ std::string &appName, std::string &pkgName)
{
- std::string appName, pkgName;
+ std::string appNameString, pkgNameString, licenseString;
try {
- m_privilegeDb.GetAppForAppDefinedPrivilege(std::make_pair(privilege, 0), uid, appName);
+ m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString);
// check if privilege is provided by globally installed application
- if (appName.empty())
- m_privilegeDb.GetAppForAppDefinedPrivilege(std::make_pair(privilege, 0), getGlobalUserId(), appName);
+ if (appNameString.empty())
+ m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString);
- m_privilegeDb.GetAppPkgName(appName, pkgName);
- if (appName.empty() || pkgName.empty()) {
+ m_privilegeDb.GetAppPkgName(appNameString, pkgNameString);
+ if (appNameString.empty() || pkgNameString.empty()) {
LogWarning("Privilege " << privilege << " not found in database");
return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
} else {
- LogDebug("Privilege: " << privilege << " provided by app: " << appName << ", pkg: " << pkgName);
+ LogDebug("Privilege: " << privilege << " provided by app: " << appNameString << ", pkg: " << pkgNameString);
}
} catch (const PrivilegeDb::Exception::Base &e) {
LogError("Error while getting appName or pkgName from database: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
}
- provider = std::make_pair(appName, pkgName);
+ appName = appNameString;
+ pkgName = pkgNameString;
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int ServiceImpl::getAppDefinedPrivilegeLicense(uid_t uid, const std::string &privilege,
+ std::string &license)
+{
+ std::string appNameString, licenseString;
+ try {
+ m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString);
+
+ // check if privilege is provided by globally installed application
+ if (appNameString.empty())
+ m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString);
+
+ if (licenseString.empty())
+ return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+ } catch (const PrivilegeDb::Exception::Base &e) {
+ LogError("Error while getting license from database: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ }
+
+ license = licenseString;
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int ServiceImpl::getClientPrivilegeLicense(const std::string &appName, uid_t uid, const std::string &privilege,
+ std::string &license)
+{
+ std::string licenseString;
+ try {
+ uid_t requestUid = m_privilegeDb.IsUserAppInstalled(appName, uid) ? uid : getGlobalUserId();
+
+ m_privilegeDb.GetLicenseForClientPrivilege(appName, requestUid, privilege, licenseString);
+
+ if (licenseString.empty())
+ return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+ } catch (const PrivilegeDb::Exception::Base &e) {
+ LogError("Error while getting license for app: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ }
+
+ license = licenseString;
return SECURITY_MANAGER_SUCCESS;
}
#include <list>
#include <map>
#include <memory>
+#include <tuple>
namespace SecurityManager {
// Abstract data stream buffer
Serialize(stream, *p);
}
+ // TODO template version without limit on tuple size
+ // std::tuple
+ template <typename A, typename B, typename C>
+ static void Serialize(IStream& stream, const std::tuple<A, B, C>& t)
+ {
+ Serialize(stream, std::get<0>(t));
+ Serialize(stream, std::get<1>(t));
+ Serialize(stream, std::get<2>(t));
+ }
+ template <typename A, typename B, typename C>
+ static void Serialize(IStream& stream, const std::tuple<A, B, C>* const t)
+ {
+ Serialize(stream, *t);
+ }
+
// std::map
template <typename K, typename T>
static void Serialize(IStream& stream, const std::map<K, T>& map)
Deserialize(stream, *p);
}
+ // TODO template version without limit on tuple size
+ // std::tuple
+ template <typename A, typename B, typename C>
+ static void Deserialize(IStream& stream, std::tuple<A, B, C>& t)
+ {
+ Deserialize(stream, std::get<0>(t));
+ Deserialize(stream, std::get<1>(t));
+ Deserialize(stream, std::get<2>(t));
+ }
+ template <typename A, typename B, typename C>
+ static void Deserialize(IStream& stream, std::tuple<A, B, C>*& t)
+ {
+ t = new std::tuple<A, B, C>;
+ Deserialize(stream, *t);
+ }
+
// std::map
template <typename K, typename T>
static void Deserialize(IStream& stream, std::map<K, T>& map)
* This function is used to add privilege to app_inst_req structure,
* it can be called multiple times
*
+ * \deprecated This function is deprecated. Use
+ * security_manager_app_inst_req_add_client_privilege() instead.
+ *
* \param[in] p_req Pointer handling app_inst_req structure
* \param[in] privilege Application privilege
* \return API return code or error code
*/
-int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege);
+int security_manager_app_inst_req_add_privilege(
+ app_inst_req *p_req,
+ const char *privilege) __attribute__((deprecated(
+ "Use security_manager_app_inst_req_add_client_privilege() instead")));
+
+/**
+ * This function is used to add privilege and license to app_inst_req structure,
+ * it can be called multiple times.
+ *
+ * \param[in] p_req Pointer handling app_inst_req structure
+ * \param[in] privilege Application privilege
+ * \param[in] license Requirements for license-manager. For type
+ * SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED this parameter
+ * must be NULL. For type SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSE
+ * this parameter may contain path to public_key/certificate (or
+ * other document) used during varification process.
+ * \return API return code or error code
+ */
+int security_manager_app_inst_req_add_client_privilege(
+ app_inst_req *p_req,
+ const char *privilege,
+ const char *license);
/**
- * This function is used to add privilege defined by application to app_inst_req structure,
+ * This function is used to add privilege and license defined by application to app_inst_req structure,
* it can be called multiple times
*
* \param[in] p_req Pointer handling app_inst_req structure
* \param[in] app_defined_privilege Privilege defined by application
* \param[in] type Privilege type
- * \param[in] license Unused parameter
+ * \param[in] license Requirements for license-manager. For type
+ * SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED this parameter
+ * must be NULL. For type SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSE
+ * this parameter may contain path to public_key/certificate (or
+ * other document) used during varification process.
* \return API return code or error code
*/
int security_manager_app_inst_req_add_app_defined_privilege(
int security_manager_shm_open(const char *name, int oflag, mode_t mode, const char *app_id);
/**
- * Get package and application id of an application which provides privilege
+ * Get package id and application id of an application which provides privilege.
*
* On successful call pkg_id and app_id should be freed when caller is done with them.
* Both pkg_id and app_id are allocated with malloc() so they should be freed with free() function.
* \param[out] app_id Application id of the provider application
* \return API return code or error code
*/
-int security_manager_identify_privilege_provider(const char *privilege, uid_t uid,
- char **pkg_id, char **app_id);
+int security_manager_get_app_defined_privilege_provider(const char *privilege,
+ uid_t uid,
+ char **pkg_id,
+ char **app_id);
+
+/**
+ * Get license of an application which provides privilege.
+ *
+ * On successful call license should be freed when caller is done with them.
+ * license is allocated with malloc() so should be freed with free() function.
+ * When privilege/uid is incorrect or not related to any license, this function will
+ * return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT.
+ *
+ * \param[in] privilege Privilege name
+ * \param[in] uid User identifier
+ * \param[out] license Data used to verify if client may use this privilege.
+ * If privilege type is SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED this
+ * value will be set to NULL.
+ * \return API return code or error code
+ */
+int security_manager_get_app_defined_privilege_license(const char *privilege,
+ uid_t uid,
+ char **license);
+
+/**
+ * Extract license from application that requested access to privilege.
+ *
+ * On successful call license should be freed when caller is done with them.
+ * license parameter will be allocated with malloc so it should be freed with free() function.
+ * When privilege/app_id/uid is incorrect or not related to any license, this function will
+ * return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT.
+ *
+ * \param[in] privilege Privilege name
+ * \param[in] app_id Id of application that request access to privilege.
+ * \param[in] uid User identifier
+ * \param[out] license Data that will be used to verify access to privilege. If privilege
+ * type is SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED this value will be
+ * set to NULL.
+ * \return API return code or error code
+ */
+int security_manager_get_client_privilege_license(const char *privilege,
+ const char *app_id,
+ uid_t uid,
+ char **license);
#ifdef __cplusplus
}
std::string smack, privilege;
int uid;
ss >> smack >> uid >> privilege;
- char *pkgId = nullptr, *appId = nullptr;
+ char *pkgId = nullptr, *appId = nullptr, *licensePath = nullptr;
- security_manager_identify_privilege_provider(
+ security_manager_get_app_defined_privilege_provider(
privilege.c_str(),
uid,
&pkgId,
&appId);
+ security_manager_get_app_defined_privilege_license(
+ privilege.c_str(),
+ uid,
+ &licensePath);
+
ALOGD("App: %s Uid: %d Priv: %s", smack.c_str(), uid, privilege.c_str());
ALOGD("Privilege: %s is Provided by: %s/%s", privilege.c_str(), appId, pkgId);
free(pkgId);
free(appId);
+ free(licensePath);
std::stringstream out;
out << 1;
* @param buffer Raw received data buffer
* @param send Raw data buffer to be sent
*/
- void processGetPrivilegeProvider(MessageBuffer &buffer, MessageBuffer &send);
+ void processGetAppDefinedPrivilegeProvider(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process getting license of privilege
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processGetAppDefinedPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process getting license of privilege
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send);
};
} // namespace SecurityManager
case SecurityModuleCall::SHM_APP_NAME:
processShmAppName(buffer, send, creds);
break;
- case SecurityModuleCall::GET_PRIVILEGE_PROVIDER:
- LogDebug("call_type: SecurityModuleCall::GET_PRIVILEGE_PROVIDER");
- processGetPrivilegeProvider(buffer, send);
+ case SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER:
+ LogDebug("call_type: SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER");
+ processGetAppDefinedPrivilegeProvider(buffer, send);
+ break;
+ case SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE:
+ LogDebug("call_type: SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE");
+ processGetAppDefinedPrivilegeLicense(buffer, send);
+ break;
+ case SecurityModuleCall::GET_CLIENT_PRIVILEGE_LICENSE:
+ LogDebug("call_type: SecurityModuleCall::GET_CLIENT_PRIVILEGE_PROVIDER");
+ processGetClientPrivilegeLicense(buffer, send);
break;
default:
LogError("Invalid call: " << call_type_int);
Serialization::Serialize(send, ret);
}
-void Service::processGetPrivilegeProvider(MessageBuffer &buffer, MessageBuffer &send)
+void Service::processGetAppDefinedPrivilegeProvider(MessageBuffer &buffer, MessageBuffer &send)
{
int ret;
- std::string privilege;
+ std::string privilege, appName, pkgName;
+ uid_t uid;
+
+ Deserialization::Deserialize(buffer, uid, privilege);
+ ret = serviceImpl.getAppDefinedPrivilegeProvider(uid, privilege, appName, pkgName);
+ Serialization::Serialize(send, ret);
+ if (ret == SECURITY_MANAGER_SUCCESS)
+ Serialization::Serialize(send, appName, pkgName);
+}
+
+void Service::processGetAppDefinedPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret;
+ std::string privilege, license;
+ uid_t uid;
+
+ Deserialization::Deserialize(buffer, uid, privilege);
+ ret = serviceImpl.getAppDefinedPrivilegeLicense(uid, privilege, license);
+ Serialization::Serialize(send, ret);
+ if (ret == SECURITY_MANAGER_SUCCESS)
+ Serialization::Serialize(send, license);
+}
+
+void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret;
+ std::string appName, privilege, license;
uid_t uid;
- std::pair<std::string, std::string> provider;
- Deserialization::Deserialize(buffer, privilege);
- Deserialization::Deserialize(buffer, uid);
- ret = serviceImpl.getPrivilegeProvider(privilege, uid, provider);
+ Deserialization::Deserialize(buffer, appName, uid, privilege);
+ ret = serviceImpl.getClientPrivilegeLicense(appName, uid, privilege, license);
Serialization::Serialize(send, ret);
if (ret == SECURITY_MANAGER_SUCCESS)
- Serialization::Serialize(send, provider);
+ Serialization::Serialize(send, license);
}
} // namespace SecurityManager
struct AppDefinedPrivilegeFixture : public PrivilegeDBFixture {
void checkAppDefinedPrivileges(const std::string &app, uid_t uid,
- const PrivilegesVector &expected);
+ const AppDefinedPrivilegesVector &expected);
};
void AppDefinedPrivilegeFixture::checkAppDefinedPrivileges(const std::string &app, uid_t uid,
- const PrivilegesVector &expected)
+ const AppDefinedPrivilegesVector &expected)
{
- PrivilegesVector privileges;
+ AppDefinedPrivilegesVector privileges;
testPrivDb->GetAppDefinedPrivileges(app, uid, privileges);
BOOST_REQUIRE_MESSAGE(privileges.size() == expected.size(), "Vector sizes differ");
for (unsigned int i = 0; i < privileges.size(); ++i) {
- BOOST_REQUIRE(privileges[i].first == expected[i].first);
- BOOST_REQUIRE(privileges[i].second == expected[i].second);
+ BOOST_REQUIRE(std::get<0>(privileges[i]) == std::get<0>(expected[i]));
+ BOOST_REQUIRE(std::get<1>(privileges[i]) == std::get<1>(expected[i]));
+ BOOST_REQUIRE(std::get<2>(privileges[i]) == std::get<2>(expected[i]));
}
}
BOOST_AUTO_TEST_CASE(T1300_app_defined_privileges)
{
// add some privileges
- PrivilegesVector privileges;
- privileges.push_back(std::make_pair("org.tizen.my_app.gps", SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED));
- privileges.push_back(std::make_pair("org.tizen.my_app.sso", SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED));
+ AppDefinedPrivilegesVector privileges;
+ privileges.push_back(std::make_tuple("org.tizen.my_app.gps",
+ SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED,
+ ""));
+ privileges.push_back(std::make_tuple("org.tizen.my_app.sso",
+ SM_APP_DEFINED_PRIVILEGE_TYPE_LICENSED,
+ "/opt/data/my_app/res/license"));
// non-existing application
checkAppDefinedPrivileges(app(1), uid(1), {});
BOOST_REQUIRE_NO_THROW(testPrivDb->AddAppDefinedPrivilege(app(1), uid(1), privileges[0]));
// check non-existing privilege
- std::string appName;
- BOOST_REQUIRE_NO_THROW(testPrivDb->GetAppForAppDefinedPrivilege(privileges[1], uid(1), appName));
+ std::string appName, license;
+ BOOST_REQUIRE_NO_THROW(
+ testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
+ appName, license));
BOOST_REQUIRE(appName.empty());
+ BOOST_REQUIRE(license.empty());
// first application defines second privilege
BOOST_REQUIRE_NO_THROW(testPrivDb->AddAppDefinedPrivilege(app(1), uid(1), privileges[1]));
// check existing privilege application name
- BOOST_REQUIRE_NO_THROW(testPrivDb->GetAppForAppDefinedPrivilege(privileges[1], uid(1), appName));
+ BOOST_REQUIRE_NO_THROW(
+ testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
+ appName, license));
BOOST_REQUIRE(appName == app(1));
+ BOOST_REQUIRE(license == std::get<2>(privileges[1]));
// check first application privileges
checkAppDefinedPrivileges(app(1), uid(1), privileges);