You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Security.cxx 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. // -=- Security.cxx
  19. #include <rfb_win32/Security.h>
  20. #include <rfb/LogWriter.h>
  21. #include <lmcons.h>
  22. #include <accctrl.h>
  23. #include <list>
  24. using namespace rfb;
  25. using namespace rfb::win32;
  26. static LogWriter vlog("SecurityWin32");
  27. Trustee::Trustee(const TCHAR* name,
  28. TRUSTEE_FORM form,
  29. TRUSTEE_TYPE type) {
  30. pMultipleTrustee = 0;
  31. MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  32. TrusteeForm = form;
  33. TrusteeType = type;
  34. ptstrName = (TCHAR*)name;
  35. }
  36. ExplicitAccess::ExplicitAccess(const TCHAR* name,
  37. TRUSTEE_FORM type,
  38. DWORD perms,
  39. ACCESS_MODE mode,
  40. DWORD inherit) {
  41. Trustee = rfb::win32::Trustee(name, type);
  42. grfAccessPermissions = perms;
  43. grfAccessMode = mode;
  44. grfInheritance = inherit;
  45. }
  46. AccessEntries::AccessEntries() : entries(0), entry_count(0) {}
  47. AccessEntries::~AccessEntries() {
  48. delete [] entries;
  49. }
  50. void AccessEntries::allocMinEntries(int count) {
  51. if (count > entry_count) {
  52. EXPLICIT_ACCESS* new_entries = new EXPLICIT_ACCESS[entry_count+1];
  53. if (entries) {
  54. memcpy(new_entries, entries, sizeof(EXPLICIT_ACCESS) * entry_count);
  55. delete entries;
  56. }
  57. entries = new_entries;
  58. }
  59. }
  60. void AccessEntries::addEntry(const TCHAR* trusteeName,
  61. DWORD permissions,
  62. ACCESS_MODE mode) {
  63. allocMinEntries(entry_count+1);
  64. ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
  65. entries[entry_count] = ExplicitAccess(trusteeName, TRUSTEE_IS_NAME, permissions, mode);
  66. entry_count++;
  67. }
  68. void AccessEntries::addEntry(const PSID sid,
  69. DWORD permissions,
  70. ACCESS_MODE mode) {
  71. allocMinEntries(entry_count+1);
  72. ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
  73. entries[entry_count] = ExplicitAccess((TCHAR*)sid, TRUSTEE_IS_SID, permissions, mode);
  74. entry_count++;
  75. }
  76. PSID Sid::copySID(const PSID sid) {
  77. if (!IsValidSid(sid))
  78. throw rdr::Exception("invalid SID in copyPSID");
  79. PSID buf = (PSID)new rdr::U8[GetLengthSid(sid)];
  80. if (!CopySid(GetLengthSid(sid), buf, sid))
  81. throw rdr::SystemException("CopySid failed", GetLastError());
  82. return buf;
  83. }
  84. void Sid::setSID(const PSID sid) {
  85. delete [] buf;
  86. buf = (rdr::U8*)copySID(sid);
  87. }
  88. void Sid::getUserNameAndDomain(TCHAR** name, TCHAR** domain) {
  89. DWORD nameLen = 0;
  90. DWORD domainLen = 0;
  91. SID_NAME_USE use;
  92. LookupAccountSid(0, (PSID)buf, 0, &nameLen, 0, &domainLen, &use);
  93. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  94. throw rdr::SystemException("Unable to determine SID name lengths", GetLastError());
  95. vlog.info("nameLen=%lu, domainLen=%lu, use=%d", nameLen, domainLen, use);
  96. *name = new TCHAR[nameLen];
  97. *domain = new TCHAR[domainLen];
  98. if (!LookupAccountSid(0, (PSID)buf, *name, &nameLen, *domain, &domainLen, &use))
  99. throw rdr::SystemException("Unable to lookup account SID", GetLastError());
  100. }
  101. Sid::Administrators::Administrators() {
  102. PSID sid = 0;
  103. SID_IDENTIFIER_AUTHORITY ntAuth = { SECURITY_NT_AUTHORITY };
  104. if (!AllocateAndInitializeSid(&ntAuth, 2,
  105. SECURITY_BUILTIN_DOMAIN_RID,
  106. DOMAIN_ALIAS_RID_ADMINS,
  107. 0, 0, 0, 0, 0, 0, &sid))
  108. throw rdr::SystemException("Sid::Administrators", GetLastError());
  109. setSID(sid);
  110. FreeSid(sid);
  111. }
  112. Sid::SYSTEM::SYSTEM() {
  113. PSID sid = 0;
  114. SID_IDENTIFIER_AUTHORITY ntAuth = { SECURITY_NT_AUTHORITY };
  115. if (!AllocateAndInitializeSid(&ntAuth, 1,
  116. SECURITY_LOCAL_SYSTEM_RID,
  117. 0, 0, 0, 0, 0, 0, 0, &sid))
  118. throw rdr::SystemException("Sid::SYSTEM", GetLastError());
  119. setSID(sid);
  120. FreeSid(sid);
  121. }
  122. Sid::FromToken::FromToken(HANDLE h) {
  123. DWORD required = 0;
  124. GetTokenInformation(h, TokenUser, 0, 0, &required);
  125. rdr::U8Array tmp(required);
  126. if (!GetTokenInformation(h, TokenUser, tmp.buf, required, &required))
  127. throw rdr::SystemException("GetTokenInformation", GetLastError());
  128. TOKEN_USER* tokenUser = (TOKEN_USER*)tmp.buf;
  129. setSID(tokenUser->User.Sid);
  130. }
  131. PACL rfb::win32::CreateACL(const AccessEntries& ae, PACL existing_acl) {
  132. PACL new_dacl;
  133. DWORD result;
  134. if ((result = SetEntriesInAcl(ae.entry_count, ae.entries, existing_acl, &new_dacl)) != ERROR_SUCCESS)
  135. throw rdr::SystemException("SetEntriesInAcl", result);
  136. return new_dacl;
  137. }
  138. PSECURITY_DESCRIPTOR rfb::win32::CreateSdWithDacl(const PACL dacl) {
  139. SECURITY_DESCRIPTOR absSD;
  140. if (!InitializeSecurityDescriptor(&absSD, SECURITY_DESCRIPTOR_REVISION))
  141. throw rdr::SystemException("InitializeSecurityDescriptor", GetLastError());
  142. Sid::SYSTEM owner;
  143. if (!SetSecurityDescriptorOwner(&absSD, owner, FALSE))
  144. throw rdr::SystemException("SetSecurityDescriptorOwner", GetLastError());
  145. Sid::Administrators group;
  146. if (!SetSecurityDescriptorGroup(&absSD, group, FALSE))
  147. throw rdr::SystemException("SetSecurityDescriptorGroupp", GetLastError());
  148. if (!SetSecurityDescriptorDacl(&absSD, TRUE, dacl, FALSE))
  149. throw rdr::SystemException("SetSecurityDescriptorDacl", GetLastError());
  150. DWORD sdSize = GetSecurityDescriptorLength(&absSD);
  151. SecurityDescriptorPtr sd(sdSize);
  152. if (!MakeSelfRelativeSD(&absSD, (PSECURITY_DESCRIPTOR)sd.ptr, &sdSize))
  153. throw rdr::SystemException("MakeSelfRelativeSD", GetLastError());
  154. return sd.takeSD();
  155. }