cmWIXAccessControlList.cxx 3.3 KB

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