Source code of Windows XP (NT5)
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.

218 lines
5.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: S E C U R I T Y . C
  7. //
  8. // Contents: Support for process-wide security settings such as calls
  9. // to CoInitializeSecurity.
  10. //
  11. // Notes:
  12. //
  13. // Author: shaunco 15 Jul 1998
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "security.h"
  19. #define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
  20. (((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
  21. DWORD
  22. DwInitializeNullDaclSdFromThreadToken (
  23. PSECURITY_DESCRIPTOR* ppSd
  24. )
  25. {
  26. PSECURITY_DESCRIPTOR pSd;
  27. PTOKEN_USER pUserInfo;
  28. PTOKEN_PRIMARY_GROUP pGroupInfo;
  29. HANDLE hToken;
  30. DWORD dwErr = NOERROR;
  31. DWORD dwUserSize;
  32. DWORD dwGroupSize;
  33. DWORD dwAlignSdSize;
  34. DWORD dwAlignUserSize;
  35. PVOID pvBuffer;
  36. // Here is the buffer we are building.
  37. //
  38. // |<- a ->|<--- b ---->|<--- c ---->|
  39. // +-------+------------+------------+
  40. // | p| p| |
  41. // | SD a| User info a| Group info |
  42. // | d| d| |
  43. // +-------+------------+------------+
  44. // ^ ^ ^
  45. // | | |
  46. // | | +--pGroupInfo
  47. // | |
  48. // | +--pUserInfo
  49. // |
  50. // +--pSd (this is returned via *ppSd)
  51. //
  52. // pad is so that pUserInfo and pGroupInfo are aligned properly.
  53. //
  54. // a = dwAlignSdSize
  55. // b = dwAlignUserSize
  56. // c = dwGroupSize
  57. //
  58. // Initialize output parameters.
  59. //
  60. *ppSd = NULL;
  61. // Open the thread token if we can. If we can't try for the process
  62. // token.
  63. //
  64. if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
  65. {
  66. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
  67. {
  68. dwErr = GetLastError ();
  69. goto finish;
  70. }
  71. }
  72. // Get the size of the buffer required for the user information.
  73. //
  74. if (!GetTokenInformation (hToken, TokenUser, NULL, 0, &dwUserSize))
  75. {
  76. dwErr = GetLastError ();
  77. if (ERROR_INSUFFICIENT_BUFFER != dwErr)
  78. {
  79. goto finish;
  80. }
  81. }
  82. // Get the size of the buffer required for the group information.
  83. //
  84. if (!GetTokenInformation (hToken, TokenPrimaryGroup, NULL, 0, &dwGroupSize))
  85. {
  86. dwErr = GetLastError ();
  87. if (ERROR_INSUFFICIENT_BUFFER != dwErr)
  88. {
  89. goto finish;
  90. }
  91. }
  92. dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(SECURITY_DESCRIPTOR_MIN_LENGTH, PTOKEN_USER);
  93. dwAlignUserSize = SIZE_ALIGNED_FOR_TYPE(dwUserSize, PTOKEN_PRIMARY_GROUP);
  94. // Allocate a buffer big enough for both making sure the sub-buffer
  95. // for the group information is suitably aligned.
  96. //
  97. pvBuffer = MemAlloc (0,
  98. dwAlignSdSize + dwAlignUserSize + dwGroupSize);
  99. if (pvBuffer)
  100. {
  101. dwErr = NOERROR;
  102. // Setup the pointers into the buffer.
  103. //
  104. pSd = pvBuffer;
  105. pUserInfo = (PTOKEN_USER)((PBYTE)pvBuffer + dwAlignSdSize);
  106. pGroupInfo = (PTOKEN_PRIMARY_GROUP)((PBYTE)pUserInfo + dwAlignUserSize);
  107. if (!InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION))
  108. {
  109. dwErr = GetLastError ();
  110. }
  111. if (!SetSecurityDescriptorDacl (pSd, TRUE, NULL, FALSE))
  112. {
  113. dwErr = GetLastError ();
  114. }
  115. if (!GetTokenInformation (hToken, TokenUser,
  116. pUserInfo, dwUserSize, &dwUserSize))
  117. {
  118. dwErr = GetLastError ();
  119. }
  120. if (!GetTokenInformation (hToken, TokenPrimaryGroup,
  121. pGroupInfo, dwGroupSize, &dwGroupSize))
  122. {
  123. dwErr = GetLastError ();
  124. }
  125. if (!SetSecurityDescriptorOwner (pSd, pUserInfo->User.Sid, FALSE))
  126. {
  127. dwErr = GetLastError ();
  128. }
  129. if (!SetSecurityDescriptorGroup (pSd, pGroupInfo->PrimaryGroup, FALSE))
  130. {
  131. dwErr = GetLastError ();
  132. }
  133. // All is well, so assign the output parameters.
  134. //
  135. if (!dwErr)
  136. {
  137. *ppSd = pSd;
  138. }
  139. // Free our allocated buffer on failure.
  140. //
  141. else
  142. {
  143. MemFree (pvBuffer);
  144. }
  145. }
  146. else
  147. {
  148. dwErr = ERROR_OUTOFMEMORY;
  149. }
  150. finish:
  151. return dwErr;
  152. }
  153. VOID
  154. InitializeSecurity (
  155. DWORD dwParam,
  156. DWORD dwAuthLevel,
  157. DWORD dwImpersonationLevel,
  158. DWORD dwAuthCapabilities
  159. )
  160. {
  161. HRESULT hr;
  162. PSECURITY_DESCRIPTOR pSd;
  163. ASSERT (0 != dwParam);
  164. if (!DwInitializeNullDaclSdFromThreadToken (&pSd))
  165. {
  166. hr = CoInitializeEx (NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
  167. if (SUCCEEDED(hr))
  168. {
  169. SVCHOST_LOG1(SECURITY,
  170. "Calling CoInitializeSecurity...(dwAuthCapabilities=0x%08x)\n",
  171. dwAuthCapabilities);
  172. hr = CoInitializeSecurity (
  173. pSd, -1, NULL, NULL,
  174. dwAuthLevel,
  175. dwImpersonationLevel,
  176. NULL,
  177. dwAuthCapabilities,
  178. NULL);
  179. if (FAILED(hr))
  180. {
  181. SVCHOST_LOG1(ERROR,
  182. "CoInitializeSecurity returned hr=0x%08x\n",
  183. hr);
  184. }
  185. }
  186. MemFree (pSd);
  187. }
  188. }