Pass application labels instead of names in security_manager_monitor 11/89911/3
authorRafal Krypa <r.krypa@samsung.com>
Tue, 27 Sep 2016 11:16:59 +0000 (13:16 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Wed, 28 Sep 2016 15:23:00 +0000 (17:23 +0200)
In an upcoming change, generation of application process label will
require additional information, application name will not be sufficient.
To keep security_manager_monitor functional and effective, it is better
to generate application label on the service side and take the labels
without further processing on the client side.

Appropriate policy migration is also provided to migrate old apps-names
files to new apps-labels.

Change-Id: Ica3b2a0dc4f3295e4ead71285684c656e34f2006
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
policy/policy-version
policy/updates/update-policy-to-v2.sh [new file with mode: 0755]
src/client/client-label-monitor.cpp
src/common/config.cpp
src/common/filesystem.cpp
src/common/include/config.h
src/common/include/filesystem.h
src/common/include/permissible-set.h
src/common/permissible-set.cpp
src/common/service_impl.cpp

index d00491fd7e5bb6fa28c517a0bb32b8b506539d4d..0cfbf08886fca9a91cb753ec8734c84fcbe52c9f 100644 (file)
@@ -1 +1 @@
-1
+2
diff --git a/policy/updates/update-policy-to-v2.sh b/policy/updates/update-policy-to-v2.sh
new file mode 100755 (executable)
index 0000000..ebfb4be
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+export PATH=/sbin:/usr/sbin:/bin:/usr/bin
+
+. /etc/tizen-platform.conf
+
+find $TZ_SYS_VAR/security-manager -name apps-names |
+while read file_old
+do
+    file_new=`dirname $file_old`/apps-labels
+    sed 's/^/User::App::/' $f <$file_old >$file_new
+    rm -f $file_old
+done
index c06a06c452043beebf8c9574bbbd2f07974978ba..9fdd11bdbd31211a8a1c085725f60f02187704a4 100644 (file)
@@ -64,15 +64,17 @@ struct app_labels_monitor {
 static lib_retcode apply_relabel_list(const std::string &global_label_file,
         const std::string &user_label_file)
 {
-    std::vector<std::string> names;
+    std::vector<std::string> appLabels;
+
     try {
-        PermissibleSet::readNamesFromPermissibleFile(global_label_file, names);
-        PermissibleSet::readNamesFromPermissibleFile(user_label_file, names);
+        PermissibleSet::readLabelsFromPermissibleFile(global_label_file, appLabels);
+        PermissibleSet::readLabelsFromPermissibleFile(user_label_file, appLabels);
         std::vector<const char*> temp;
-        std::transform(names.begin(), names.end(), std::back_inserter(temp),
-                [] (std::string &label) {label = SmackLabels::generateAppLabel(label);
-                    return label.c_str();});
-        if (smack_set_relabel_self(const_cast<const char **>(temp.data()), temp.size()) != 0) {
+
+        std::transform(appLabels.begin(), appLabels.end(), std::back_inserter(temp),
+                [] (std::string &label) {return label.c_str();});
+
+        if (smack_set_relabel_self(temp.data(), temp.size()) != 0) {
             LogError("smack_set_relabel_self failed");
             return SECURITY_MANAGER_ERROR_SET_RELABEL_SELF_FAILED;
         }
@@ -162,7 +164,7 @@ void security_manager_app_labels_monitor_finish(app_labels_monitor *monitor)
                 int ret = inotify_rm_watch(monitorPtr->inotify, monitorPtr->global_labels_file_watch);
                 if (ret == -1) {
                     LogError("Inotify watch removal failed on file " <<
-                            Config::APPS_NAME_FILE << ": " << GetErrnoString(errno));
+                            Config::APPS_LABELS_FILE << ": " << GetErrnoString(errno));
                 }
             }
             if (monitorPtr->user_labels_file_watch != -1) {
index 342e706265ab13828c3e9ba89d242cbd7aa884f7..fa12770d34693b8480c3db3df11bd0894a5f30b5 100644 (file)
@@ -37,7 +37,7 @@ const std::string PRIVILEGE_POLICY_USER      = "http://tizen.org/privilege/notex
 const std::string PRIVILEGE_POLICY_ADMIN     = "http://tizen.org/privilege/internal/usermanagement";
 const std::string PRIVILEGE_APPSHARING_ADMIN = "http://tizen.org/privilege/notexist";
 
-const std::string APPS_NAME_FILE = "apps-names";
+const std::string APPS_LABELS_FILE = "apps-labels";
 const std::string SKEL_DIR = "/etc/skel";
 
 const std::string PRIVACY_POLICY_DESC = "Ask user";
index 0993a6ad7aa7def0b4ada47ac411a2382e9b8d5b..b7699bfc74094dbed723c421e2b6842d7c0eb98e 100644 (file)
@@ -86,6 +86,18 @@ FileNameVector getDirContents(const std::string &path, const mode_t &mode)
     return result;
 }
 
+std::string dirName(const std::string &path)
+{
+    size_t slashPos = path.find_last_of('/');
+
+    if (slashPos == std::string::npos)
+        return ".";
+    else if (slashPos == 0)
+        return "/";
+    else
+        return path.substr(0, slashPos);
+}
+
 } // namespace FS
 } // nanespace SecurityManager
 
index c6aeb7c897a964cac7dcd2cb16e73f98a67d248e..f3f9864227c2d2607482cf5637e63ea23347fd00 100644 (file)
@@ -43,7 +43,7 @@ extern const std::string PRIVILEGE_POLICY_ADMIN;
 extern const std::string PRIVILEGE_APPSHARING_ADMIN;
 
 /* Files used in permitted label managment */
-extern const std::string APPS_NAME_FILE;
+extern const std::string APPS_LABELS_FILE;
 
 extern const std::string SKEL_DIR;
 
index 9806edb93b56ebc585ab9d119bdf7d08c9560e53..9c4783604372e8c837e27027a461a864b1c138a4 100644 (file)
@@ -37,6 +37,7 @@ typedef std::vector<std::string> FileNameVector;
 FileNameVector getDirContents(const std::string &path, const mode_t &mode);
 FileNameVector getFilesFromDirectory(const std::string &path);
 FileNameVector getDirsFromDirectory(const std::string &path);
+std::string dirName(const std::string &path);
 
 } // namespace FS
 } // nanespace SecurityManager
index f29debd32ed1f66284a2b18654a493d33ab6b525..f3810d4c3f385c9a4533c08ba3218c811ff64fda 100644 (file)
@@ -43,16 +43,20 @@ public:
     DECLARE_EXCEPTION_TYPE(Base, FileOpenError)
     DECLARE_EXCEPTION_TYPE(Base, FileReadError)
     DECLARE_EXCEPTION_TYPE(Base, FileWriteError)
+    DECLARE_EXCEPTION_TYPE(Base, FileInitError)
+    DECLARE_EXCEPTION_TYPE(Base, FileRemoveError)
 };
+
 /**
- * Return path to file with current list of application names
+ * Return path to file with current list of application labels
  * installed globally or locally for the user.
  *
  * @param[in] uid identifier of the user whose application it should be
  * @param[in] installationType type of installation (global or local)
- * @return path to file with names
+ * @return path to file with labels
  */
 std::string getPerrmissibleFileLocation(uid_t uid, int installationType);
+
 /**
  * Update permissable file with current content of database
  * @throws FileLockError
@@ -64,17 +68,23 @@ std::string getPerrmissibleFileLocation(uid_t uid, int installationType);
  * @return resulting true on success
  */
 void updatePermissibleFile(uid_t uid, int installationType);
+
 /**
- * Read names from a file into a vector
+ * Read labels from a file into a vector
  * @throws FileLockError
  * @throws FileOpenError
  * @throws FileReadError
  *
- * @param[in] nameFile contains application names
- * @param[out] names vector to which application names are added
+ * @param[in] nameFile path to the labels file
+ * @param[out] appLabels vector to which application labels are added
  * @return SECURITY_MANAGER_SUCCESS or error code
  */
-void readNamesFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &names);
+void readLabelsFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &appLabels);
+
+void initializeUserPermissibleFile(uid_t uid);
+
+void removeUserPermissibleFile(uid_t uid);
+
 } // PermissibleSet
 } // SecurityManager
 #endif /* _PERMISSIBLE_SET_H_ */
index 62d0b29f8be2792be5aaa0aeed0bf5bd78f70293..8915b10b6cc43ca6d8040b5a2f6eb32dda933332 100644 (file)
 #include <cstdio>
 #include <cstring>
 #include <fstream>
+#include <linux/xattr.h>
 #include <memory>
 #include <pwd.h>
 #include <string>
 #include <sys/file.h>
+#include <sys/smack.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <dpl/exception.h>
 #include <dpl/fstream_accessors.h>
 #include <dpl/log/log.h>
+#include <filesystem.h>
 #include <permissible-set.h>
 #include <privilege_db.h>
 #include <security-manager-types.h>
+#include <smack-labels.h>
 #include <tzplatform_config.h>
 
 #include "tzplatform-config.h"
@@ -81,12 +85,10 @@ std::string getPerrmissibleFileLocation(uid_t uid, int installationType)
     if ((installationType == SM_APP_INSTALL_GLOBAL)
             || (installationType == SM_APP_INSTALL_PRELOADED))
         return tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME,
-                              Config::APPS_NAME_FILE.c_str());
-    else {
-        std::string user = tpc.ctxGetEnv(TZ_USER_NAME);
-        return tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME, user,
-                              Config::APPS_NAME_FILE.c_str());
-    }
+            Config::APPS_LABELS_FILE);
+    else
+        return tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME,
+            tpc.ctxGetEnv(TZ_USER_NAME), Config::APPS_LABELS_FILE);
 }
 
 static void markPermissibleFileValid(int fd, const std::string &nameFile, bool valid)
@@ -108,10 +110,11 @@ void updatePermissibleFile(uid_t uid, int installationType)
     std::ofstream fstream;
     openAndLockNameFile(nameFile, fstream);
     markPermissibleFileValid(getFd(fstream), nameFile, false);
+
     std::vector<std::string> appNames;
     PrivilegeDb::getInstance().GetUserApps(uid, appNames);
-    for (auto &name : appNames) {
-        fstream << name << '\n';
+    for (auto &appName : appNames) {
+        fstream << SmackLabels::generateAppLabel(appName) << '\n';
         if (fstream.bad()) {
             LogError("Unable to write to file " << nameFile << ": " << GetErrnoString(errno));
             ThrowMsg(PermissibleSetException::PermissibleSetException::FileWriteError,
@@ -129,14 +132,14 @@ void updatePermissibleFile(uid_t uid, int installationType)
     markPermissibleFileValid(getFd(fstream), nameFile, true);
 }
 
-void readNamesFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &names)
+void readLabelsFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &appLabels)
 {
     std::ifstream fstream;
     openAndLockNameFile(nameFile, fstream);
 
     std::string line;
     while (std::getline(fstream, line))
-        names.push_back(line);
+        appLabels.push_back(line);
 
     if (fstream.bad()) {
         LogError("Failure while reading file " << nameFile << ": " << GetErrnoString(errno));
@@ -144,5 +147,37 @@ void readNamesFromPermissibleFile(const std::string &nameFile, std::vector<std::
     }
 }
 
+void initializeUserPermissibleFile(uid_t uid)
+{
+    std::string nameFile = getPerrmissibleFileLocation(uid, SM_APP_INSTALL_LOCAL);
+    std::string nameDir = FS::dirName(nameFile);
+
+    if (mkdir(nameDir.c_str(), 0755) != 0 && errno != EEXIST)
+        ThrowMsg(PermissibleSetException::FileInitError,
+            "Unable to create directory for user permissible file:" << GetErrnoString(errno));
+
+    std::ofstream fstream;
+    openAndLockNameFile(nameFile, fstream);
+    if (smack_set_label_for_file(getFd(fstream), XATTR_NAME_SMACK, "_") != 0)
+        ThrowMsg(PermissibleSetException::FileInitError,
+            "Unable to set Smack label for user permissible file");
+
+    markPermissibleFileValid(getFd(fstream), nameFile, true);
+}
+
+void removeUserPermissibleFile(uid_t uid)
+{
+    std::string nameFile = getPerrmissibleFileLocation(uid, SM_APP_INSTALL_LOCAL);
+    std::string nameDir = FS::dirName(nameFile);
+
+    if (unlink(nameFile.c_str()) != 0 && errno != ENOENT)
+        ThrowMsg(PermissibleSetException::FileRemoveError,
+            "Unable to remove user permissible file:" << GetErrnoString(errno));
+
+    if (rmdir(nameFile.c_str()) != 0 && errno != ENOENT)
+        ThrowMsg(PermissibleSetException::FileRemoveError,
+            "Unable to remove directory for user permissible file:" << GetErrnoString(errno));
+}
+
 } // PermissibleSet
 } // SecurityManager
index 96be37f84827635d047d548a5de330d9fea2b909..5989092d9560216604dbd6e2831672a3562ffe0e 100644 (file)
@@ -149,45 +149,6 @@ bool fileExists(const std::string &path) {
     return (stat(path.c_str(), &buffer) == 0) && S_ISREG(buffer.st_mode);
 }
 
-lib_retcode makeDirIfNotExists(const std::string &path, mode_t mode, const std::string &label)
-{
-    if (mkdir(path.c_str(), mode) != 0 && errno != EEXIST) {
-        LogError("Creation of directory " + path + "failed");
-        return SECURITY_MANAGER_ERROR_FILE_CREATE_FAILED;
-    }
-    if (smack_set_label_for_path(path.c_str(), XATTR_NAME_SMACK, 0, label.c_str()) < 0) {
-        LogError("Setting smack label failed for: " << path);
-        return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
-    }
-    return SECURITY_MANAGER_SUCCESS;
-}
-
-lib_retcode initializeUserAppsNameConfig(uid_t userAdded, const std::string &label) {
-    TizenPlatformConfig tpc(userAdded);
-    std::string user = tpc.ctxGetEnv(TZ_USER_NAME);
-    std::string userDirectory = tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME, user);
-    std::string userFile = tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME, user,
-                                           Config::APPS_NAME_FILE);
-    lib_retcode ret = makeDirIfNotExists(userDirectory, S_IRUSR|S_IXUSR|S_IWUSR|S_IXGRP|S_IXOTH,
-                                         label);
-    if (ret != SECURITY_MANAGER_SUCCESS)
-        return ret;
-    int fd = open(userFile.c_str(), O_CREAT|O_WRONLY, S_IRUSR|S_IRGRP|S_IROTH);
-    if (fd == -1) {
-        LogError("File creation failed with: " << GetErrnoString(errno) << " for: " << userFile);
-        return SECURITY_MANAGER_ERROR_FILE_CREATE_FAILED;
-    }
-    if (smack_set_label_for_file(fd, XATTR_NAME_SMACK, label.c_str()) < 0) {
-        LogError("Setting smack label for file: " << userFile << "failed");
-        return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
-    }
-    if (close(fd) == -1) {
-        LogWarning("Close of file failed with: " << GetErrnoString(errno) << " for: " << userFile);
-    }
-
-    return SECURITY_MANAGER_SUCCESS;
-}
-
 class ScopedTransaction {
 public:
     ScopedTransaction() : m_isCommited(false) {
@@ -832,12 +793,13 @@ int ServiceImpl::userAdd(const Credentials &creds, uid_t uidAdded, int userType)
         return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
     }
     try {
-        lib_retcode ret;
         CynaraAdmin::getInstance().UserInit(uidAdded, static_cast<security_manager_user_type>(userType), isPrivilegePrivacy);
-        if ((ret = initializeUserAppsNameConfig(uidAdded, "_")) != SECURITY_MANAGER_SUCCESS)
-            return ret;
+        PermissibleSet::initializeUserPermissibleFile(uidAdded);
     } catch (CynaraException::InvalidParam &e) {
         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+    } catch (const PermissibleSet::PermissibleSetException::FileInitError &e) {
+        LogError("Error while adding user: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
     } catch (const std::exception &e) {
         LogError("Memory allocation error while adding user: " << e.what());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
@@ -858,9 +820,16 @@ int ServiceImpl::userDelete(const Credentials &creds, uid_t uidDeleted)
     std::vector<std::string> userApps;
     try {
         PrivilegeDb::getInstance().GetUserApps(uidDeleted, userApps);
+        PermissibleSet::removeUserPermissibleFile(uidDeleted);
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while getting user apps from database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    } catch (const PermissibleSet::PermissibleSetException::FileRemoveError &e) {
+        LogError("Error while removing user: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_FILE_DELETE_FAILED;
+    } catch (const std::exception &e) {
+        LogError("Memory allocation error while deleting user: " << e.what());
+        return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     }
 
     // Don't check whether the caller may uninstall apps of the removed user
@@ -876,32 +845,7 @@ int ServiceImpl::userDelete(const Credentials &creds, uid_t uidDeleted)
             ret = SECURITY_MANAGER_ERROR_SERVER_ERROR;
         }
     }
-    try {
-        TizenPlatformConfig tpc(uidDeleted);
-        std::string user = tpc.ctxGetEnv(TZ_USER_NAME);
-        std::string userDirectory = tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME, user);
-        std::string userFile = tpc.ctxMakePath(TZ_SYS_VAR, Config::SERVICE_NAME, user,
-                                               Config::APPS_NAME_FILE);
-        int res = unlink(userFile.c_str());
-        if (res) {
-            if (errno != ENOENT) {
-                LogError("File deletion failed with: " << GetErrnoString(errno) <<
-                         " for: " << userFile);
-                ret = SECURITY_MANAGER_ERROR_FILE_DELETE_FAILED;
-            }
-        }
-        res = rmdir(userDirectory.c_str());
-        if (res) {
-            if (errno != ENOENT) {
-                LogError("Directory deletion failed with: " << GetErrnoString(errno) <<
-                         " for: " << userDirectory);
-                ret = SECURITY_MANAGER_ERROR_FILE_DELETE_FAILED;
-            }
-        }
-    } catch (const std::exception &e) {
-        LogError("Memory allocation error while deleting user: " << e.what());
-        return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    }
+
     CynaraAdmin::getInstance().UserRemove(uidDeleted);
 
     return ret;