Accept null as appId during license extraction 78/132178/9
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 1 Jun 2017 10:12:09 +0000 (12:12 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 13 Jun 2017 09:54:16 +0000 (11:54 +0200)
In non-hybrid application appId is not placed
inside smack label. Non-hybrid application could
not be idenitified. We can only retrieve its pkgId.

Change-Id: I52d35fab45dbf494dfc8a2de84c38d63d29b781d

src/client/client-security-manager.cpp
src/common/include/privilege_db.h
src/common/include/service_impl.h
src/common/privilege_db.cpp
src/common/service_impl.cpp
src/include/app-runtime.h
src/license-manager/agent/agent_logic.cpp
src/server/service/service.cpp
test/test_privilege_db_app_defined_privileges.cpp

index b449b82..32037da 100644 (file)
@@ -534,7 +534,7 @@ struct kernel_sigaction {
 };
 
 #if __x86_64__
-void restore_rt(void) __asm__ ("__restore_rt");
+void restore_rt(void) __asm__("__restore_rt");
 
 #define RESTORE(name, syscall) RESTORE2(name, syscall)
 #define RESTORE2(name, syscall) \
@@ -1705,21 +1705,23 @@ int security_manager_get_app_defined_privilege_license(
 SECURITY_MANAGER_API
 int security_manager_get_client_privilege_license(
         const char *privilege,
+        const char *pkg_name,
         const char *app_name,
         uid_t uid,
         char **license)
 {
     return try_catch([&]() -> int {
         using namespace SecurityManager;
+        std::string appName(app_name ? app_name : "");
         LogDebug(__PRETTY_FUNCTION__ << " called");
 
-        if (privilege == NULL || app_name == NULL || license == NULL) {
-            LogError("privilege, app_name, license could not be NULL");
+        if (!privilege || !pkg_name || !license) {
+            LogError("privilege, pkg_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())
+        if (request.send(appName, std::string(pkg_name), uid, std::string(privilege)).failed())
             return request.getStatus();
 
         std::string licenseString;
index d4f4210..3465eb3 100644 (file)
@@ -86,9 +86,10 @@ enum class StmtType {
     ERemoveAppDefinedPrivileges,
     ERemoveClientPrivileges,
     EGetAppDefinedPrivileges,
-    EGetAppAndLicenseForAppDefinedPrivilege,
-    EGetLicenseForClientPrivilege,
-    EIsUserAppInstalled,
+    EGetAppPkgLicenseForAppDefinedPrivilege,
+    EGetLicenseForClientPrivilegeAndApp,
+    EGetLicenseForClientPrivilegeAndPkg,
+    EIsUserPkgInstalled,
 };
 
 // privilege, app_defined_privilege_type, license
@@ -152,9 +153,10 @@ private:
         { StmtType::ERemoveAppDefinedPrivileges, "DELETE FROM app_defined_privilege_view WHERE app_name = ? 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 = ?"},
+        { StmtType::EGetAppPkgLicenseForAppDefinedPrivilege, "SELECT app_name, pkg_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?"},
+        { StmtType::EGetLicenseForClientPrivilegeAndApp, "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? "},
+        { StmtType::EGetLicenseForClientPrivilegeAndPkg, "SELECT license FROM client_license_view WHERE pkg_name = ? AND uid = ? AND privilege = ? "},
+        { StmtType::EIsUserPkgInstalled, "SELECT count(*) FROM user_app_pkg_view WHERE pkg_name = ? AND uid = ?"},
     };
 
     /**
@@ -627,15 +629,17 @@ public:
      * @param[in]  uid - user identifier
      * @param[in]  privilege - privilege identifier
      * @param[out] appName - application identifier
+     * @param[out] pkgName - application package
      * @param[out] license - verification factor required by license-manager
      *
      * @exception PrivilegeDb::Exception::InternalError on internal error
      * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
      * @return true if data were found in the database
      */
-    bool GetAppAndLicenseForAppDefinedPrivilege(uid_t uid,
+    bool GetAppPkgLicenseForAppDefinedPrivilege(uid_t uid,
                                                 const std::string &privilege,
                                                 std::string &appName,
+                                                std::string &pkgName,
                                                 std::string &license);
 
     /**
@@ -650,18 +654,35 @@ public:
      * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
      * @return true if data were found in the database
      */
-    bool GetLicenseForClientPrivilege(const std::string &appName,
-                                      uid_t uid,
-                                      const std::string &privilege,
-                                      std::string &license);
+    bool GetLicenseForClientPrivilegeAndApp(const std::string &appName,
+                                            uid_t uid,
+                                            const std::string &privilege,
+                                            std::string &license);
+    /**
+     * Retrieve license of client application
+     *
+     * @param[in]  pkgName - application package
+     * @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
+     * @return true if data were found in the database
+     */
+    bool GetLicenseForClientPrivilegeAndPkg(const std::string &pkgName,
+                                            uid_t uid,
+                                            const std::string &privilege,
+                                            std::string &license);
+
 
     /**
-     * Check whether user has installed application
+     * Check whether user has installed package
      *
      * @exception PrivilegeDb::Exception::InternalError on internal error
      * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
      */
-    bool IsUserAppInstalled(const std::string& appName, uid_t uid);
+    bool IsUserPkgInstalled(const std::string& pkgName, uid_t uid);
 };
 
 } //namespace SecurityManager
index 7366867..782dff0 100644 (file)
@@ -277,14 +277,16 @@ public:
      * Retrieves the license associated with given privilege and uid.
      *
      * @param[in]  appName   application identifier
+     * @param[in]  pkgName   package identifier
+     *
      * @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 getClientPrivilegeLicense(const std::string &appName, uid_t uid,
-                                  const std::string &privilege,
+    int getClientPrivilegeLicense(const std::string &appName, const std::string &pkgName,
+                                  uid_t uid, const std::string &privilege,
                                   std::string &license);
 
 private:
@@ -345,6 +347,8 @@ private:
 
     int validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap);
 
+    int getAppDefinedPrivilegeDescription(uid_t uid, const std::string &privilege, std::string &appName, std::string &pkgName, std::string &license);
+
     Cynara m_cynara;
     PrivilegeDb m_privilegeDb;
     CynaraAdmin m_cynaraAdmin;
index 9ee6569..3f955e8 100644 (file)
@@ -687,24 +687,27 @@ void PrivilegeDb::GetAppDefinedPrivileges(const std::string &appName, uid_t uid,
     });
 }
 
-bool PrivilegeDb::GetAppAndLicenseForAppDefinedPrivilege(
+bool PrivilegeDb::GetAppPkgLicenseForAppDefinedPrivilege(
         uid_t uid,
         const std::string &privilege,
         std::string &appName,
+        std::string &pkgName,
         std::string &license)
 {
     return try_catch<bool>([&] {
         appName.clear();
+        pkgName.clear();
         license.clear();
 
-        auto command = getStatement(StmtType::EGetAppAndLicenseForAppDefinedPrivilege);
+        auto command = getStatement(StmtType::EGetAppPkgLicenseForAppDefinedPrivilege);
         command->BindInteger(1, uid);
         command->BindString(2, privilege);
 
         if (command->Step()) {
             appName = command->GetColumnString(0);
-            license = command->GetColumnString(1);
-            LogDebug("Privilege: " << privilege << " defined by " << appName);
+            pkgName = command->GetColumnString(1);
+            license = command->GetColumnString(2);
+            LogDebug("Privilege: " << privilege << " defined by " << appName << " " << pkgName);
             return true;
         }
 
@@ -713,7 +716,7 @@ bool PrivilegeDb::GetAppAndLicenseForAppDefinedPrivilege(
     });
 }
 
-bool PrivilegeDb::GetLicenseForClientPrivilege(
+bool PrivilegeDb::GetLicenseForClientPrivilegeAndApp(
         const std::string &appName,
         uid_t uid,
         const std::string &privilege,
@@ -722,7 +725,7 @@ bool PrivilegeDb::GetLicenseForClientPrivilege(
     return try_catch<bool>([&] {
         license.clear();
 
-        auto command = getStatement(StmtType::EGetLicenseForClientPrivilege);
+        auto command = getStatement(StmtType::EGetLicenseForClientPrivilegeAndApp);
         command->BindString(1, appName);
         command->BindInteger(2, uid);
         command->BindString(3, privilege);
@@ -740,11 +743,38 @@ bool PrivilegeDb::GetLicenseForClientPrivilege(
     });
 }
 
-bool PrivilegeDb::IsUserAppInstalled(const std::string& appName, uid_t uid)
+bool PrivilegeDb::GetLicenseForClientPrivilegeAndPkg(
+        const std::string &pkgName,
+        uid_t uid,
+        const std::string &privilege,
+        std::string &license)
+{
+    return try_catch<bool>([&] {
+        license.clear();
+
+        auto command = getStatement(StmtType::EGetLicenseForClientPrivilegeAndPkg);
+        command->BindString(1, pkgName);
+        command->BindInteger(2, uid);
+        command->BindString(3, privilege);
+
+        if (command->Step()) {
+            license = command->GetColumnString(0);
+            LogDebug("License found for pkg: " << pkgName << " privilege: " <<
+                privilege << " uid: " << uid << " License: " << license);
+            return true;
+        }
+
+        LogDebug("License not found for pkg: " << pkgName << " privilege: " <<
+            privilege << " uid: " << uid);
+        return false;
+    });
+}
+
+bool PrivilegeDb::IsUserPkgInstalled(const std::string& pkgName, uid_t uid)
 {
     return try_catch<bool>([&]() -> bool {
-        auto command = getStatement(StmtType::EIsUserAppInstalled);
-        command->BindString(1, appName);
+        auto command = getStatement(StmtType::EIsUserPkgInstalled);
+        command->BindString(1, pkgName);
         command->BindInteger(2, uid);
         int isInstalled = 0;
 
index 0e49485..a46c0de 100644 (file)
@@ -1756,79 +1756,112 @@ int ServiceImpl::shmAppName(const Credentials &creds, const std::string &shmName
     return SECURITY_MANAGER_SUCCESS;
 }
 
-int ServiceImpl::getAppDefinedPrivilegeProvider(uid_t uid, const std::string &privilege,
-                                                std::string &appName, std::string &pkgName)
+int ServiceImpl::getAppDefinedPrivilegeDescription(
+        uid_t uid,
+        const std::string &privilege,
+        std::string &appName,
+        std::string &pkgName,
+        std::string &license)
 {
-    std::string appNameString, pkgNameString, licenseString;
     try {
-        // Get appName and License
-        if (!m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString) &&
-            !m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString))
+        // Local provider have priority. Search for local provider.
+        if (m_privilegeDb.GetAppPkgLicenseForAppDefinedPrivilege(uid, privilege, appName, pkgName, license))
+        {
+            // We found local provider. We may return it.
+            return SECURITY_MANAGER_SUCCESS;
+        }
+
+        // Local provider not found. Search for global provider.
+        std::string localAppName, localPkgName, localLicense;
+        if (!m_privilegeDb.GetAppPkgLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, localAppName, localPkgName, localLicense))
         {
             LogDebug("Privilege " << privilege << " not found in database");
             return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
         }
 
-        // Convert appName to pkgName
-        m_privilegeDb.GetAppPkgName(appNameString, pkgNameString);
-
-        if (appNameString.empty() || pkgNameString.empty()) {
-            LogWarning("Could not translate appName to pkgName. appName: " << appName);
+        // Global provider found. Check if it's not hidden by local installation of application with same pkgName.
+        if (m_privilegeDb.IsUserPkgInstalled(localPkgName, uid))
+        {
+            // Ups. There is local installation of application with the same pkgId (it does not provide privilege).
+            // Global provider could not be used!
+            LogDebug("Local installation hiddes global one. Local installation of pkg: " << localPkgName << " does not support: " << privilege);
             return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
         }
 
-        LogDebug("Privilege: " << privilege << " provided by app: " << appNameString << " pkg: " << pkgNameString);
+        // Return result
+        appName = std::move(localAppName);
+        pkgName = std::move(localPkgName);
+        license = std::move(localLicense);
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while getting appName or pkgName from database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     }
-
-    appName = appNameString;
-    pkgName = pkgNameString;
     return SECURITY_MANAGER_SUCCESS;
 }
 
-int ServiceImpl::getAppDefinedPrivilegeLicense(uid_t uid, const std::string &privilege,
-                                                std::string &license)
+int ServiceImpl::getAppDefinedPrivilegeProvider(
+        uid_t uid,
+        const std::string &privilege,
+        std::string &appName,
+        std::string &pkgName)
 {
-    std::string appNameString, licenseString;
-    try {
-        if (!m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString) &&
-            !m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString))
-        {
-            LogDebug("Privilege " << privilege << " is not found in database");
-            return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
-        }
+    std::string localLicense;
+    return getAppDefinedPrivilegeDescription(uid, privilege, appName, pkgName, localLicense);
+}
 
-        if (licenseString.empty()) {
-            LogWarning("Empty license was found in database for privlege: " << privilege);
-            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;
+int ServiceImpl::getAppDefinedPrivilegeLicense(
+        uid_t uid,
+        const std::string &privilege,
+        std::string &license)
+{
+    std::string localAppName, localPkgName, localLicense;
+    int ret = getAppDefinedPrivilegeDescription(uid, privilege, localAppName, localPkgName, localLicense);
+
+    if (ret != SECURITY_MANAGER_SUCCESS) {
+        return ret;
+    }
+
+    if (localLicense.empty()) {
+        return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
     }
 
-    license = licenseString;
+    license = std::move(localLicense);
     return SECURITY_MANAGER_SUCCESS;
 }
 
-int ServiceImpl::getClientPrivilegeLicense(const std::string &appName, uid_t uid, const std::string &privilege,
-                                           std::string &license)
+int ServiceImpl::getClientPrivilegeLicense(
+        const std::string &appName,
+        const std::string &pkgName,
+        uid_t uid,
+        const std::string &privilege,
+        std::string &license)
 {
-    std::string licenseString;
     try {
-        uid_t requestUid = m_privilegeDb.IsUserAppInstalled(appName, uid) ? uid : getGlobalUserId();
+        std::string licenseString;
+        uid_t requestUid = m_privilegeDb.IsUserPkgInstalled(pkgName, uid) ? uid : getGlobalUserId();
+
+        if (m_privilegeDb.IsPackageHybrid(pkgName)) {
+            if (appName.empty()) {
+                LogDebug("appName could not be empty if you ask about hybrid application");
+                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+            }
 
-        if (!m_privilegeDb.GetLicenseForClientPrivilege(appName, requestUid, privilege, licenseString)) {
+            if (!m_privilegeDb.GetLicenseForClientPrivilegeAndApp(appName, requestUid, privilege, licenseString)) {
+                LogDebug("License was not found for privilege: " << privilege << " appId: " << appName << " and uid: " << requestUid);
+                return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+            }
+        } else if (!m_privilegeDb.GetLicenseForClientPrivilegeAndPkg(pkgName, requestUid, privilege, licenseString)) {
+            LogDebug("License was not found for privilege: " << privilege << " pkgId: " << pkgName << " and uid: " << requestUid);
             return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
         }
+
+        license = std::move(licenseString);
+
     } 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;
 }
 
index 945b6a9..fa4226d 100644 (file)
@@ -264,11 +264,13 @@ int security_manager_get_app_defined_privilege_license(const char *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.
+ * When privilege/pkg_id/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]  pkg_id      Package Id of application that request of license.
+ * \param[in]  app_id      Id of application that request access to privilege (null for
+ *                         non-hybrid application).
  * \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
@@ -276,6 +278,7 @@ int security_manager_get_app_defined_privilege_license(const char *privilege,
  * \return API return code or error code
  */
 int security_manager_get_client_privilege_license(const char *privilege,
+                                                  const char *pkg_id,
                                                   const char *app_id,
                                                   uid_t uid,
                                                   char **license);
index eb96d32..76c1038 100644 (file)
@@ -101,6 +101,7 @@ int verify(const std::string &smack, int uid, const std::string &privilege) {
 
     if (SECURITY_MANAGER_SUCCESS != security_manager_get_client_privilege_license(
             privilege.c_str(),
+            clientPkgId,
             clientAppId,
             uid,
             &clientLicensePath))
index 16511bf..983d86b 100644 (file)
@@ -460,11 +460,11 @@ void Service::processGetAppDefinedPrivilegeLicense(MessageBuffer &buffer, Messag
 void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send)
 {
     int ret;
-    std::string appName, privilege, license;
+    std::string appName, pkgName, privilege, license;
     uid_t uid;
 
-    Deserialization::Deserialize(buffer, appName, uid, privilege);
-    ret = serviceImpl.getClientPrivilegeLicense(appName, uid, privilege, license);
+    Deserialization::Deserialize(buffer, appName, pkgName, uid, privilege);
+    ret = serviceImpl.getClientPrivilegeLicense(appName, pkgName, uid, privilege, license);
     Serialization::Serialize(send, ret);
     if (ret == SECURITY_MANAGER_SUCCESS)
         Serialization::Serialize(send, license);
index 82eca27..da33da6 100644 (file)
@@ -61,7 +61,7 @@ void AppDefinedPrivilegeFixture::checkClientLicense(const std::string &app, uid_
 
     for (unsigned int i = 0; i < privileges.size(); ++i) {
         std::string license;
-        BOOST_REQUIRE(expected[i].first == testPrivDb->GetLicenseForClientPrivilege(app, uid, privileges[i], license));
+        BOOST_REQUIRE(expected[i].first == testPrivDb->GetLicenseForClientPrivilegeAndApp(app, uid, privileges[i], license));
         BOOST_REQUIRE(license == expected[i].second);
     }
 }
@@ -102,11 +102,12 @@ BOOST_AUTO_TEST_CASE(T1300_app_defined_privileges)
                         PrivilegeDb::Exception::ConstraintError);
 
     // check non-existing privilege
-    std::string appName, license;
+    std::string appName, pkgName, license;
     BOOST_REQUIRE_NO_THROW(
-        testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
-                                                           appName, license));
+        testPrivDb->GetAppPkgLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
+                                                           appName, pkgName, license));
     BOOST_REQUIRE(appName.empty());
+    BOOST_REQUIRE(pkgName.empty());
     BOOST_REQUIRE(license.empty());
 
     // first application defines second privilege
@@ -114,9 +115,10 @@ BOOST_AUTO_TEST_CASE(T1300_app_defined_privileges)
 
     // check existing privilege application name
     BOOST_REQUIRE_NO_THROW(
-        testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
-                                                           appName, license));
+        testPrivDb->GetAppPkgLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]),
+                                                           appName, pkgName, license));
     BOOST_REQUIRE(appName == app(1));
+    BOOST_REQUIRE(pkgName == pkg(1));
     BOOST_REQUIRE(license == std::get<2>(privileges[1]));
 
     // check first application privileges
@@ -193,7 +195,7 @@ BOOST_AUTO_TEST_CASE(T1400_client_license)
 
     // check non-existing privilege
     std::string license;
-    BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilege(app(1), uid(1), privilegesA[1].first, license));
+    BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilegeAndApp(app(1), uid(1), privilegesA[1].first, license));
     BOOST_REQUIRE(license.empty());
 
     // first application use second privilege/license
@@ -213,7 +215,7 @@ BOOST_AUTO_TEST_CASE(T1400_client_license)
     BOOST_REQUIRE_NO_THROW(testPrivDb->AddClientPrivilege(app(2), uid(2), privilegesB[0].first, privilegesB[0].second));
 
     // check non-existing privilege
-    BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilege(app(2), uid(2), privilegesB[1].first, license));
+    BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilegeAndApp(app(2), uid(2), privilegesB[1].first, license));
     BOOST_REQUIRE(license.empty());
 
     // second application use second privilege/license