diff options
-rw-r--r-- | sessiond/src/fs_helpers.cpp | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/sessiond/src/fs_helpers.cpp b/sessiond/src/fs_helpers.cpp index 123ea7e..c8132b2 100644 --- a/sessiond/src/fs_helpers.cpp +++ b/sessiond/src/fs_helpers.cpp @@ -99,6 +99,30 @@ std::string fs_helpers::get_smack_label(std::string_view src_path, smack_label_t return out_str; } +static int copy_label(auto label, auto dest_path, auto type) +{ + if (type != SMACK_LABEL_TRANSMUTE) + return smack_lsetlabel(dest_path.data(), label.c_str(), type); + + /* Setting TRANSMUTE attribute needs special attention: + * the only correct values are: NULL, "", "0" or "1" */ + if (label == "TRUE") + return smack_lsetlabel(dest_path.data(), "1", type); + + /* N.B. This is a bit tricky. Since TRANSMUTE attribute is inheritable, + * it is possible that it was set to TRUE while copying the files from + * /etc/skel, but originally it wasn't there in the source directory for + * some subdirectories/files. Therefore it must be removed explicitly. */ + int ret = smack_lsetlabel(dest_path.data(), "0", type); + if (ret == -1 && errno == -ENODATA) { + /* We tried to drop the label, but it already didn't exist, + * so the "error" is expected and not a problem. */ + return 0; + } + + return ret; +} + void fs_helpers::copy_smack_attributes(std::string_view src_path, std::string_view dest_path) { static const enum smack_label_type label_types[] = { @@ -108,34 +132,8 @@ void fs_helpers::copy_smack_attributes(std::string_view src_path, std::string_vi for (const auto type : label_types) { auto label = get_smack_label(src_path, type); - int ret = 0; - - if (type == SMACK_LABEL_TRANSMUTE) { - // N.B. Setting TRANSMUTE attribute needs special attention: - // the only correct values are: NULL, "", "0" or "1". - if (label == "TRUE") - ret = smack_lsetlabel(dest_path.data(), "1", type); - else { - /* N.B. This is a bit tricky. Since TRANSMUTE attribute is inheritable, - * it is possible that it was set to TRUE while copying the files from - * /etc/skel, but originally it wasn't there in the source directory for - * some subdirectories/files. Therefore it must be removed, but here is - * another caveat: TRANSMUTE can only be dropped if it was previously set. */ - auto dest_lbl = get_smack_label(dest_path.data(), type); - if (dest_lbl == "TRUE") { - ret = smack_lsetlabel(dest_path.data(), "0", type); - if (ret == -1 && errno == ENODATA) { - /* We tried to drop the label, but it already didn't exist, - * so this return value is correct and expected. */ - ret = 0; - } - } - } - } - else - ret = smack_lsetlabel(dest_path.data(), label.c_str(), type); - if (ret) + if (copy_label(label, dest_path, type)) throw std::runtime_error( "Couldn't set SMACK attributes of destination directory: "s + dest_path.data()); |