diff options
Diffstat (limited to 'Source/CPack/WiX/cmWIXAccessControlList.cxx')
-rw-r--r-- | Source/CPack/WiX/cmWIXAccessControlList.cxx | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx new file mode 100644 index 0000000..bbbd92d --- /dev/null +++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx @@ -0,0 +1,136 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmWIXAccessControlList.h" + +#include <CPack/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"); +} |