fs-helpers: [fix] Keep owner of files/directories while copying 63/274463/1
authorAdam Michalski <a.michalski2@partner.samsung.com>
Thu, 28 Apr 2022 13:11:46 +0000 (15:11 +0200)
committerAdam Michalski <a.michalski2@partner.samsung.com>
Thu, 28 Apr 2022 13:36:03 +0000 (15:36 +0200)
Seems that `std::filesystem` doesn't know the concept of Unix
file/directory ownership. It does preserve permissions while copying,
but unfortunately does not preserve the ownership.

Change-Id: I0492b7beef2460bd4ce71fba34553e52dc299b54

sessiond/src/fs_helpers.cpp
sessiond/src/fs_helpers.h

index ccf7522e7418a028c21ee6870d04bb0add182524..41b55300057d8af9dd674c478e04de223bae914e 100644 (file)
@@ -23,6 +23,7 @@
 #include <grp.h>
 #include <pwd.h>
 #include <sys/smack.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <cstring>
@@ -56,6 +57,24 @@ std::string fs_helpers::get_home_dir_by_user_id(const int uid)
        return std::string(pass_ptr->pw_dir);
 }
 
+void fs_helpers::copy_ownership(std::string_view src_path, std::string_view dest_path)
+{
+       struct stat info;
+       int ret = stat(src_path.data(), &info);
+
+       if (ret)
+               throw std::system_error(errno, std::system_category(),
+                       std::string("Couldn't stat `")
+                       + src_path.data()
+                       + "` file/directory");
+
+       if (chown(dest_path.data(), info.st_uid, info.st_gid) == -1)
+               throw std::system_error(errno, std::system_category(),
+                       std::string("Couldn't set owner/group of the `")
+                       + dest_path.data()
+                       + "` file/directory");
+}
+
 void fs_helpers::copy_smack_attributes(const std::string &src_path, const std::string &dest_path)
 {
        static const enum smack_label_type label_types[] = {
@@ -163,7 +182,7 @@ void fs_helpers::add_user_subsession(const int session_uid, const int subsession
                        | fs::copy_options::copy_symlinks
                );
 
-               // Copy SMACK attributes for `apps_rw/*` subdirectories
+               // Copy ownership and SMACK attributes for `apps_rw/*` subdirectories & files
                for (auto const& entry : fs::recursive_directory_iterator(source_dir)) {
                        std::string s_path = entry.path();
 
@@ -171,9 +190,11 @@ void fs_helpers::add_user_subsession(const int session_uid, const int subsession
                        tmp_path.erase(0, source_dir_len);
                        std::string d_path = apps_rw_tmp_dir + tmp_path;
 
+                       copy_ownership(s_path, d_path);
                        copy_smack_attributes(s_path, d_path);
                }
                // Last but not least - the `apps_rw` directory itself
+               copy_ownership(source_dir, apps_rw_tmp_dir);
                copy_smack_attributes(source_dir, apps_rw_tmp_dir);
 
                // Copy + rename so that the replacement is atomic
index e806ed6b44684b434f0087ec7f7485c818924a64..ca2d605a75017f79fc13f5f954144c3a7c72628d 100644 (file)
@@ -13,6 +13,7 @@ namespace fs_helpers
        fs::path get_subsession_dir_by_uid(const int session_uid);
 
        void create_main_subdirectory(const int session_uid, std::string_view main_dir);
+       void copy_ownership(std::string_view src_path, std::string_view dest_path);
        void copy_smack_attributes(const std::string &src_path, const std::string &dest_path);
        void add_user_subsession(const int session_uid, const int subsession_id);
        void remove_user_subsession(const int session_uid, const int subsession_id);