cmWIXAccessControlList.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmWIXAccessControlList.h"
  4. #include <cm/string_view>
  5. #include "cmCPackGenerator.h"
  6. #include "cmStringAlgorithms.h"
  7. #include "cmSystemTools.h"
  8. cmWIXAccessControlList::cmWIXAccessControlList(
  9. cmCPackLog* logger, cmInstalledFile const& installedFile,
  10. cmWIXSourceWriter& sourceWriter)
  11. : Logger(logger)
  12. , InstalledFile(installedFile)
  13. , SourceWriter(sourceWriter)
  14. {
  15. }
  16. bool cmWIXAccessControlList::Apply()
  17. {
  18. std::vector<std::string> entries;
  19. this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
  20. for (std::string const& entry : entries) {
  21. this->CreatePermissionElement(entry);
  22. }
  23. return true;
  24. }
  25. void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
  26. {
  27. std::string::size_type pos = entry.find('=');
  28. if (pos == std::string::npos) {
  29. this->ReportError(entry, "Did not find mandatory '='");
  30. return;
  31. }
  32. cm::string_view enview(entry);
  33. cm::string_view user_and_domain = enview.substr(0, pos);
  34. cm::string_view permission_string = enview.substr(pos + 1);
  35. pos = user_and_domain.find('@');
  36. cm::string_view user;
  37. cm::string_view domain;
  38. if (pos != std::string::npos) {
  39. user = user_and_domain.substr(0, pos);
  40. domain = user_and_domain.substr(pos + 1);
  41. } else {
  42. user = user_and_domain;
  43. }
  44. std::vector<std::string> permissions = cmTokenize(permission_string, ",");
  45. this->SourceWriter.BeginElement("Permission");
  46. this->SourceWriter.AddAttribute("User", std::string(user));
  47. if (!domain.empty()) {
  48. this->SourceWriter.AddAttribute("Domain", std::string(domain));
  49. }
  50. for (std::string const& permission : permissions) {
  51. this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
  52. }
  53. this->SourceWriter.EndElement("Permission");
  54. }
  55. void cmWIXAccessControlList::ReportError(std::string const& entry,
  56. std::string const& message)
  57. {
  58. cmCPackLogger(cmCPackLog::LOG_ERROR,
  59. "Failed processing ACL entry '" << entry << "': " << message
  60. << std::endl);
  61. }
  62. bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
  63. {
  64. static const char* validAttributes[] = {
  65. /* clang-format needs this comment to break after the opening brace */
  66. "Append",
  67. "ChangePermission",
  68. "CreateChild",
  69. "CreateFile",
  70. "CreateLink",
  71. "CreateSubkeys",
  72. "Delete",
  73. "DeleteChild",
  74. "EnumerateSubkeys",
  75. "Execute",
  76. "FileAllRights",
  77. "GenericAll",
  78. "GenericExecute",
  79. "GenericRead",
  80. "GenericWrite",
  81. "Notify",
  82. "Read",
  83. "ReadAttributes",
  84. "ReadExtendedAttributes",
  85. "ReadPermission",
  86. "SpecificRightsAll",
  87. "Synchronize",
  88. "TakeOwnership",
  89. "Traverse",
  90. "Write",
  91. "WriteAttributes",
  92. "WriteExtendedAttributes",
  93. 0
  94. };
  95. size_t i = 0;
  96. while (validAttributes[i]) {
  97. if (name == validAttributes[i++])
  98. return true;
  99. }
  100. return false;
  101. }
  102. void cmWIXAccessControlList::EmitBooleanAttribute(std::string const& entry,
  103. std::string const& name)
  104. {
  105. if (!this->IsBooleanAttribute(name)) {
  106. std::ostringstream message;
  107. message << "Unknown boolean attribute '" << name << "'";
  108. this->ReportError(entry, message.str());
  109. }
  110. this->SourceWriter.AddAttribute(name, "yes");
  111. }