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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. #ifdef HAVE_CONFIG_H
  20. #include <config.h>
  21. #endif
  22. #include <rfb_win32/Security.h>
  23. #include <rfb/LogWriter.h>
  24. #include <lmcons.h>
  25. #include <accctrl.h>
  26. #include <list>
  27. using namespace rfb;
  28. using namespace rfb::win32;
  29. static LogWriter vlog("SecurityWin32");
  30. Trustee::Trustee(const TCHAR* name,
  31. TRUSTEE_FORM form,
  32. TRUSTEE_TYPE type) {
  33. pMultipleTrustee = 0;
  34. MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  35. TrusteeForm = form;
  36. TrusteeType = type;
  37. ptstrName = (TCHAR*)name;
  38. }
  39. ExplicitAccess::ExplicitAccess(const TCHAR* name,
  40. TRUSTEE_FORM type,
  41. DWORD perms,
  42. ACCESS_MODE mode,
  43. DWORD inherit) {
  44. Trustee = rfb::win32::Trustee(name, type);
  45. grfAccessPermissions = perms;
  46. grfAccessMode = mode;
  47. grfInheritance = inherit;
  48. }
  49. AccessEntries::AccessEntries() : entries(0), entry_count(0) {}
  50. AccessEntries::~AccessEntries() {
  51. delete [] entries;
  52. }
  53. void AccessEntries::allocMinEntries(int count) {
  54. if (count > entry_count) {
  55. EXPLICIT_ACCESS* new_entries = new EXPLICIT_ACCESS[entry_count+1];
  56. if (entries) {
  57. memcpy(new_entries, entries, sizeof(EXPLICIT_ACCESS) * entry_count);
  58. delete entries;
  59. }
  60. entries = new_entries;
  61. }
  62. }
  63. void AccessEntries::addEntry(const TCHAR* trusteeName,
  64. DWORD permissions,
  65. ACCESS_MODE mode) {
  66. allocMinEntries(entry_count+1);
  67. ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
  68. entries[entry_count] = ExplicitAccess(trusteeName, TRUSTEE_IS_NAME, permissions, mode);
  69. entry_count++;
  70. }
  71. void AccessEntries::addEntry(const PSID sid,
  72. DWORD permissions,
  73. ACCESS_MODE mode) {
  74. allocMinEntries(entry_count+1);
  75. ZeroMemory(&entries[entry_count], sizeof(EXPLICIT_ACCESS));
  76. entries[entry_count] = ExplicitAccess((TCHAR*)sid, TRUSTEE_IS_SID, permissions, mode);
  77. entry_count++;
  78. }
  79. PSID Sid::copySID(const PSID sid) {
  80. if (!IsValidSid(sid))
  81. throw rdr::Exception("invalid SID in copyPSID");
  82. PSID buf = (PSID)new rdr::U8[GetLengthSid(sid)];
  83. if (!CopySid(GetLengthSid(sid), buf, sid))
  84. throw rdr::SystemException("CopySid failed", GetLastError());
  85. return buf;
  86. }
  87. void Sid::setSID(const PSID sid) {
  88. delete [] buf;
  89. buf = (rdr::U8*)copySID(sid);
  90. }
  91. void Sid::getUserNameAndDomain(TCHAR** name, TCHAR** domain) {
  92. DWORD nameLen = 0;
  93. DWORD domainLen = 0;
  94. SID_NAME_USE use;
  95. LookupAccountSid(0, (PSID)buf, 0, &nameLen, 0, &domainLen, &use);
  96. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  97. throw rdr::SystemException("Unable to determine SID name lengths", GetLastError());
  98. vlog.info("nameLen=%lu, domainLen=%lu, use=%d", nameLen, domainLen, use);
  99. *name = new TCHAR[nameLen];
  100. *domain = new TCHAR[domainLen];
  101. if (!LookupAccountSid(0, (PSID)buf, *name, &nameLen, *domain, &domainLen, &use))
  102. throw rdr::SystemException("Unable to lookup account SID", GetLastError());
  103. }
  104. Sid::Administrators::Administrators() {
  105. PSID sid = 0;
  106. SID_IDENTIFIER_AUTHORITY ntAuth = { SECURITY_NT_AUTHORITY };
  107. if (!AllocateAndInitializeSid(&ntAuth, 2,
  108. SECURITY_BUILTIN_DOMAIN_RID,
  109. DOMAIN_ALIAS_RID_ADMINS,
  110. 0, 0, 0, 0, 0, 0, &sid))
  111. throw rdr::SystemException("Sid::Administrators", GetLastError());
  112. setSID(sid);
  113. FreeSid(sid);
  114. }
  115. Sid::SYSTEM::SYSTEM() {
  116. PSID sid = 0;
  117. SID_IDENTIFIER_AUTHORITY ntAuth = { SECURITY_NT_AUTHORITY };
  118. if (!AllocateAndInitializeSid(&ntAuth, 1,
  119. SECURITY_LOCAL_SYSTEM_RID,
  120. 0, 0, 0, 0, 0, 0, 0, &sid))
  121. throw rdr::SystemException("Sid::SYSTEM", GetLastError());
  122. setSID(sid);
  123. FreeSid(sid);
  124. }
  125. Sid::FromToken::FromToken(HANDLE h) {
  126. DWORD required = 0;
  127. GetTokenInformation(h, TokenUser, 0, 0, &required);
  128. rdr::U8Array tmp(required);
  129. if (!GetTokenInformation(h, TokenUser, tmp.buf, required, &required))
  130. throw rdr::SystemException("GetTokenInformation", GetLastError());
  131. TOKEN_USER* tokenUser = (TOKEN_USER*)tmp.buf;
  132. setSID(tokenUser->User.Sid);
  133. }
  134. PACL rfb::win32::CreateACL(const AccessEntries& ae, PACL existing_acl) {
  135. PACL new_dacl;
  136. DWORD result;
  137. if ((result = SetEntriesInAcl(ae.entry_count, ae.entries, existing_acl, &new_dacl)) != ERROR_SUCCESS)
  138. throw rdr::SystemException("SetEntriesInAcl", result);
  139. return new_dacl;
  140. }
  141. PSECURITY_DESCRIPTOR rfb::win32::CreateSdWithDacl(const PACL dacl) {
  142. SECURITY_DESCRIPTOR absSD;
  143. if (!InitializeSecurityDescriptor(&absSD, SECURITY_DESCRIPTOR_REVISION))
  144. throw rdr::SystemException("InitializeSecurityDescriptor", GetLastError());
  145. Sid::SYSTEM owner;
  146. if (!SetSecurityDescriptorOwner(&absSD, owner, FALSE))
  147. throw rdr::SystemException("SetSecurityDescriptorOwner", GetLastError());
  148. Sid::Administrators group;
  149. if (!SetSecurityDescriptorGroup(&absSD, group, FALSE))
  150. throw rdr::SystemException("SetSecurityDescriptorGroupp", GetLastError());
  151. if (!SetSecurityDescriptorDacl(&absSD, TRUE, dacl, FALSE))
  152. throw rdr::SystemException("SetSecurityDescriptorDacl", GetLastError());
  153. DWORD sdSize = GetSecurityDescriptorLength(&absSD);
  154. SecurityDescriptorPtr sd(sdSize);
  155. if (!MakeSelfRelativeSD(&absSD, (PSECURITY_DESCRIPTOR)sd.ptr, &sdSize))
  156. throw rdr::SystemException("MakeSelfRelativeSD", GetLastError());
  157. return sd.takeSD();
  158. }