From: Krzysztof Sasiak Date: Thu, 19 Feb 2015 10:33:20 +0000 (+0100) Subject: List policy API tests X-Git-Tag: security-manager_5.5_testing~109^2~34 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Ftest%2Fsecurity-tests.git;a=commitdiff_plain;h=049069b656bd8497b2f5e060d59c27cb7008c2c2 List policy API tests Change-Id: I71b5d1026d1263f9ef674f371b9c4c5226d8dd26 Signed-off-by: Krzysztof Sasiak --- diff --git a/tests/security-manager-tests/CMakeLists.txt b/tests/security-manager-tests/CMakeLists.txt index e0254c6..c0894ec 100644 --- a/tests/security-manager-tests/CMakeLists.txt +++ b/tests/security-manager-tests/CMakeLists.txt @@ -62,12 +62,15 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/tests/libprivilege-control-tests/common/ ) +FIND_PACKAGE(Threads) + ADD_EXECUTABLE(${TARGET_SEC_MGR_TESTS} ${SEC_MGR_SOURCES}) TARGET_LINK_LIBRARIES(${TARGET_SEC_MGR_TESTS} ${SEC_MGR_TESTS_DEP_LIBRARIES} dpl-test-framework tests-common + ${CMAKE_THREAD_LIBS_INIT} ) INSTALL(TARGETS ${TARGET_SEC_MGR_TESTS} DESTINATION /usr/bin) diff --git a/tests/security-manager-tests/security_manager_tests.cpp b/tests/security-manager-tests/security_manager_tests.cpp index 82953f0..9d9df10 100644 --- a/tests/security-manager-tests/security_manager_tests.cpp +++ b/tests/security-manager-tests/security_manager_tests.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,12 +6,17 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include + #include #include @@ -55,6 +61,56 @@ static const std::string EXEC_FILE("exec"); static const std::string NORMAL_FILE("normal"); static const std::string LINK_PREFIX("link_to_"); +static const std::string PRIVILEGE_MANAGER_APP = "privilege_manager"; +static const std::string PRIVILEGE_MANAGER_PKG = "privilege_manager"; +static const std::string PRIVILEGE_MANAGER_SELF_PRIVILEGE = "http://tizen.org/privilege/systemsettings"; +static const std::string PRIVILEGE_MANAGER_ADMIN_PRIVILEGE = "http://tizen.org/privilege/systemsettings.admin"; + +static const std::vector MANY_APPS = { + "security_manager_10_app_1", + "security_manager_10_app_2", + "security_manager_10_app_3", + "security_manager_10_app_4", + "security_manager_10_app_5" +}; + +static const std::map MANY_APPS_PKGS = { + {"security_manager_10_app_1", "security_manager_10_pkg_1"}, + {"security_manager_10_app_2", "security_manager_10_pkg_2"}, + {"security_manager_10_app_3", "security_manager_10_pkg_3"}, + {"security_manager_10_app_4", "security_manager_10_pkg_4"}, + {"security_manager_10_app_5", "security_manager_10_pkg_5"}, + {PRIVILEGE_MANAGER_APP, PRIVILEGE_MANAGER_PKG} +}; + +static const std::vector MANY_APPS_PRIVILEGES = { + { + "http://tizen.org/privilege/internet", + "http://tizen.org/privilege/location" + }, + { + "http://tizen.org/privilege/telephony", + "http://tizen.org/privilege/camera" + }, + { + "http://tizen.org/privilege/contact.read", + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email" + }, + { + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email", + "http://tizen.org/privilege/telephony", + "http://tizen.org/privilege/camera" + }, + { + "http://tizen.org/privilege/internet", + "http://tizen.org/privilege/location", + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email" + } +}; + static void generateAppLabel(const std::string &pkgId, std::string &label) { (void) pkgId; @@ -278,6 +334,40 @@ static void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pk check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); } +static inline void register_current_process_as_privilege_manager(uid_t uid, bool forAdmin = false) +{ + InstallRequest request; + request.setAppId(PRIVILEGE_MANAGER_APP.c_str()); + request.setPkgId(PRIVILEGE_MANAGER_PKG.c_str()); + request.setUid(uid); + request.addPrivilege(PRIVILEGE_MANAGER_SELF_PRIVILEGE.c_str()); + if (forAdmin) + request.addPrivilege(PRIVILEGE_MANAGER_ADMIN_PRIVILEGE.c_str()); + Api::install(request); + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); +}; + +static inline struct passwd *getUserStruct(const std::string &userName) { + struct passwd *pw = nullptr; + errno = 0; + + while(!(pw = getpwnam(userName.c_str()))) { + RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed"); + }; + + return pw; +}; + +static inline struct passwd *getUserStruct(const uid_t uid) { + struct passwd *pw = nullptr; + errno = 0; + + while(!(pw = getpwuid(uid))) { + RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed"); + }; + + return pw; +}; RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) @@ -807,6 +897,669 @@ RUNNER_CHILD_TEST(security_manager_09_add_user_offline) check_app_after_uninstall(app_id, pkg_id, true); } +RUNNER_TEST(security_manager_10_privacy_manager_fetch_whole_policy_for_self) +{ + //TEST DATA + const std::string username("sm_test_10_user_name"); + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + apps2PrivsMap.insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + ++privileges_count; + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + TemporaryTestUser tmpUser(username, GUM_USERTYPE_NORMAL, false); + tmpUser.create(); + + for(const auto &user : users2AppsMap) { + + for(const auto &app : user.second) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(tmpUser.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + //Start child process + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + int status; + wait(&status); + + tmpUser.remove(); + }; + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno); + //the above call, registers 1 new privilege for the given user, hence the incrementation of below variable + + struct passwd *pw = getUserStruct(username); + register_current_process_as_privilege_manager(pw->pw_uid); + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + exit(0); + }; +} + +RUNNER_TEST(security_manager_11_privacy_manager_fetch_whole_policy_for_admin_unprivileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_11_user_name_1", "sm_test_11_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + //Only entries for one of the users will be listed + privileges_count = 0; + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(0)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + ++privileges_count; + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users) { + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + //Start child + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + int status; + wait(&status); + + for(auto &user : users) { + user.remove(); + }; + }; + + if (pid == 0) { + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno); + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + errno = 0; + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + + //this call should only return privileges belonging to the current uid + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + exit(0); + }; +} + +RUNNER_TEST(security_manager_12_privacy_manager_fetch_whole_policy_for_admin_privileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_12_user_name_1", "sm_test_12_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE, PRIVILEGE_MANAGER_ADMIN_PRIVILEGE})); + + privileges_count += 2; + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + //Install apps for both users + for(const auto &user : users) { + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + + //Start child + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + //Wait for child to finish + int status; + wait(&status); + + for(auto &user : users) { + user.remove(); + }; + }; + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno); + + struct passwd *pw = getUserStruct(usernames.at(1)); + register_current_process_as_privilege_manager(pw->pw_uid, true); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + //this call should succeed as the calling user is privileged + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + + exit(0); + }; +} + +RUNNER_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_unprivileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_13_user_name_1", "sm_test_13_user_name_2"}; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + //TEST DATA END + + pid_t pid[2]; + sem_t *mutex[2]; + errno = 0; + RUNNER_ASSERT_MSG(((mutex[0] = sem_open("mutex_1", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #1, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(((mutex[1] = sem_open("mutex_2", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #2, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex[0], 1, 0) == 0, "failed to setup mutex #1, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex[1], 1, 0) == 0, "failed to setup mutex #2, errno: " << errno); + std::vector policyEntries; + + pid[0] = fork(); + + if(pid[0] == 0) { //child #1 process + RUNNER_ASSERT_MSG(sem_wait(mutex[0]) == 0, "sem_wait in child #1 failed, errno: " << errno); + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry filter; + PolicyRequest policyRequest; + //this call should succeed as the calling user is privileged + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + PolicyEntry policyEntry( + MANY_APPS[0], + std::to_string(pw->pw_uid), + "http://tizen.org/privilege/internet" + ); + policyEntry.setLevel("Deny"); + + policyRequest.addEntry(policyEntry); + policyEntry = PolicyEntry( + MANY_APPS[1], + std::to_string(pw->pw_uid), + "http://tizen.org/privilege/location" + ); + policyEntry.setLevel("Deny"); + + policyRequest.addEntry(policyEntry); + Api::sendPolicy(policyRequest); + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size()); + exit(0); + }; + + if (pid[0] != 0) {//parent process + pid[1] = fork(); + + if (pid[1] == 0) { //child #2 process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex[1]) == 0, "sem_wait in child #2 failed, errno: " << errno); + struct passwd *pw_target = getUserStruct(usernames.at(0)); + struct passwd *pw = getUserStruct(usernames.at(1)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry filter = PolicyEntry( + SECURITY_MANAGER_ANY, + std::to_string(pw_target->pw_uid), + SECURITY_MANAGER_ANY + ); + + //U2 requests contents of U1 privacy manager - should fail + Api::getPolicyForSelf(filter, policyEntries); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + filter = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY + ); + + policyEntries.clear(); + + //U2 requests contents of ADMIN bucket - should fail + Api::getPolicyForAdmin(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + exit(0); + }; + + if (pid[1] != 0) { //parent + + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users2AppsMap) { + + for(const auto &app : user.second) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(users.at(0).getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + + int status; + //Start child #1 + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex[0]) == 0, "Error while opening mutex #1, errno: " << errno); + + //Wait until child #1 finishes + pid_t ret = wait(&status); + RUNNER_ASSERT_MSG((ret != -1) && WIFEXITED(status), "Updating privileges failed"); + + //Start child #2 + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex[1]) == 0, "Error while opening mutex #2, errno: " << errno); + //Wait until child #2 finishes + ret = wait(&status); + RUNNER_ASSERT_MSG((ret =-1) && WIFEXITED(status), "Listing privileges failed"); + + for(auto &user : users) { + user.remove(); + }; + + sem_close(mutex[0]); + sem_close(mutex[1]); + }; + }; +} + +RUNNER_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_for_admin) +{ + //TEST DATA + const std::vector usernames = {"sm_test_14_user_name_1", "sm_test_14_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + privileges_count += 2; + //TEST DATA END + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + + pid_t pid = fork(); + if (pid != 0) { + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users) { + + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + }; + //Start child process + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + int status; + //Wait for child process to finish + wait(&status); + + //switch back to root + for(auto &user : users) { + user.remove(); + }; + + sem_close(mutex); + } + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno); + + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid, true); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyRequest *policyRequest = new PolicyRequest(); + PolicyEntry filter; + std::vector policyEntries; + //this call should succeed as the calling user is privileged + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + PolicyEntry policyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/internet" + ); + policyEntry.setMaxLevel("Deny"); + + policyRequest->addEntry(policyEntry); + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/location" + ); + policyEntry.setMaxLevel("Deny"); + + policyRequest->addEntry(policyEntry); + Api::sendPolicy(*policyRequest); + Api::getPolicyForAdmin(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size()); + + delete policyRequest; + policyRequest = new PolicyRequest(); + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/internet" + ); + policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE); + policyRequest->addEntry(policyEntry); + + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/location" + ); + policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE); + + policyRequest->addEntry(policyEntry); + Api::sendPolicy(*policyRequest); + + policyEntries.clear(); + Api::getPolicyForAdmin(filter, policyEntries); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Number of policies doesn't match - should be: 0 and is " << policyEntries.size()); + + delete policyRequest; + + exit(0); + }; + +} + int main(int argc, char *argv[]) { return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);