summaryrefslogtreecommitdiff
path: root/Source/CPack/WiX/cmWIXAccessControlList.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CPack/WiX/cmWIXAccessControlList.cxx')
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx126
1 files changed, 126 insertions, 0 deletions
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
new file mode 100644
index 000000000..744a93298
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -0,0 +1,126 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmWIXAccessControlList.h"
+
+#include "cmCPackGenerator.h"
+
+#include "cmSystemTools.h"
+
+cmWIXAccessControlList::cmWIXAccessControlList(
+ cmCPackLog* logger, cmInstalledFile const& installedFile,
+ cmWIXSourceWriter& sourceWriter)
+ : Logger(logger)
+ , InstalledFile(installedFile)
+ , SourceWriter(sourceWriter)
+{
+}
+
+bool cmWIXAccessControlList::Apply()
+{
+ std::vector<std::string> entries;
+ this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
+
+ for (size_t i = 0; i < entries.size(); ++i) {
+ this->CreatePermissionElement(entries[i]);
+ }
+
+ return true;
+}
+
+void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
+{
+ std::string::size_type pos = entry.find('=');
+ if (pos == std::string::npos) {
+ this->ReportError(entry, "Did not find mandatory '='");
+ return;
+ }
+
+ std::string user_and_domain = entry.substr(0, pos);
+ std::string permission_string = entry.substr(pos + 1);
+
+ pos = user_and_domain.find('@');
+ std::string user;
+ std::string domain;
+ if (pos != std::string::npos) {
+ user = user_and_domain.substr(0, pos);
+ domain = user_and_domain.substr(pos + 1);
+ } else {
+ user = user_and_domain;
+ }
+
+ std::vector<std::string> permissions =
+ cmSystemTools::tokenize(permission_string, ",");
+
+ this->SourceWriter.BeginElement("Permission");
+ this->SourceWriter.AddAttribute("User", user);
+ if (!domain.empty()) {
+ this->SourceWriter.AddAttribute("Domain", domain);
+ }
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ this->EmitBooleanAttribute(entry,
+ cmSystemTools::TrimWhitespace(permissions[i]));
+ }
+ this->SourceWriter.EndElement("Permission");
+}
+
+void cmWIXAccessControlList::ReportError(std::string const& entry,
+ std::string const& message)
+{
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed processing ACL entry '"
+ << entry << "': " << message << std::endl);
+}
+
+bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
+{
+ static const char* validAttributes[] = {
+ /* clang-format needs this comment to break after the opening brace */
+ "Append",
+ "ChangePermission",
+ "CreateChild",
+ "CreateFile",
+ "CreateLink",
+ "CreateSubkeys",
+ "Delete",
+ "DeleteChild",
+ "EnumerateSubkeys",
+ "Execute",
+ "FileAllRights",
+ "GenericAll",
+ "GenericExecute",
+ "GenericRead",
+ "GenericWrite",
+ "Notify",
+ "Read",
+ "ReadAttributes",
+ "ReadExtendedAttributes",
+ "ReadPermission",
+ "SpecificRightsAll",
+ "Synchronize",
+ "TakeOwnership",
+ "Traverse",
+ "Write",
+ "WriteAttributes",
+ "WriteExtendedAttributes",
+ 0
+ };
+
+ size_t i = 0;
+ while (validAttributes[i]) {
+ if (name == validAttributes[i++])
+ return true;
+ }
+
+ return false;
+}
+
+void cmWIXAccessControlList::EmitBooleanAttribute(std::string const& entry,
+ std::string const& name)
+{
+ if (!this->IsBooleanAttribute(name)) {
+ std::ostringstream message;
+ message << "Unknown boolean attribute '" << name << "'";
+ this->ReportError(entry, message.str());
+ }
+
+ this->SourceWriter.AddAttribute(name, "yes");
+}