Leaked source code of windows server 2003
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.

294 lines
8.0 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. extern "C"
  17. {
  18. #include "pch.h"
  19. }
  20. #pragma hdrstop
  21. extern "C"
  22. {
  23. #include "security.h"
  24. }
  25. #include <accctrl.h>
  26. #include <aclapi.h>
  27. #include <globalopt.h>
  28. #define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
  29. (((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
  30. const SID AUTHENTICATED_USERS_SID = {SID_REVISION, 1, {0,0,0,0,0,5}, SECURITY_AUTHENTICATED_USER_RID };
  31. DWORD
  32. DwInitializeSdFromThreadToken (
  33. PSECURITY_DESCRIPTOR* ppSd,
  34. PACL* ppAcl
  35. )
  36. {
  37. PSECURITY_DESCRIPTOR pSd;
  38. PTOKEN_USER pUserInfo;
  39. PTOKEN_PRIMARY_GROUP pGroupInfo;
  40. HANDLE hToken;
  41. DWORD dwErr = NOERROR;
  42. DWORD dwUserSize;
  43. DWORD dwGroupSize;
  44. DWORD dwAlignSdSize;
  45. DWORD dwAlignUserSize;
  46. PVOID pvBuffer;
  47. PACL pAcl = NULL;
  48. // Here is the buffer we are building.
  49. //
  50. // |<- a ->|<--- b ---->|<--- c ---->|
  51. // +-------+------------+------------+
  52. // | p| p| |
  53. // | SD a| User info a| Group info |
  54. // | d| d| |
  55. // +-------+------------+------------+
  56. // ^ ^ ^
  57. // | | |
  58. // | | +--pGroupInfo
  59. // | |
  60. // | +--pUserInfo
  61. // |
  62. // +--pSd (this is returned via *ppSd)
  63. //
  64. // pad is so that pUserInfo and pGroupInfo are aligned properly.
  65. //
  66. // a = dwAlignSdSize
  67. // b = dwAlignUserSize
  68. // c = dwGroupSize
  69. //
  70. // Initialize output parameters.
  71. //
  72. *ppSd = NULL;
  73. *ppAcl = NULL;
  74. // Open the thread token if we can. If we can't try for the process
  75. // token.
  76. //
  77. if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
  78. {
  79. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
  80. {
  81. dwErr = GetLastError ();
  82. goto finish;
  83. }
  84. }
  85. // Get the size of the buffer required for the user information.
  86. //
  87. if (!GetTokenInformation (hToken, TokenUser, NULL, 0, &dwUserSize))
  88. {
  89. dwErr = GetLastError ();
  90. if (ERROR_INSUFFICIENT_BUFFER != dwErr)
  91. {
  92. goto finish;
  93. }
  94. }
  95. // Get the size of the buffer required for the group information.
  96. //
  97. if (!GetTokenInformation (hToken, TokenPrimaryGroup, NULL, 0, &dwGroupSize))
  98. {
  99. dwErr = GetLastError ();
  100. if (ERROR_INSUFFICIENT_BUFFER != dwErr)
  101. {
  102. goto finish;
  103. }
  104. }
  105. dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(SECURITY_DESCRIPTOR_MIN_LENGTH, PTOKEN_USER);
  106. dwAlignUserSize = SIZE_ALIGNED_FOR_TYPE(dwUserSize, PTOKEN_PRIMARY_GROUP);
  107. // Allocate a buffer big enough for both making sure the sub-buffer
  108. // for the group information is suitably aligned.
  109. //
  110. pvBuffer = MemAlloc (0,
  111. dwAlignSdSize + dwAlignUserSize + dwGroupSize);
  112. if (pvBuffer)
  113. {
  114. dwErr = NOERROR;
  115. // Setup the pointers into the buffer.
  116. //
  117. pSd = pvBuffer;
  118. pUserInfo = (PTOKEN_USER)((PBYTE)pvBuffer + dwAlignSdSize);
  119. pGroupInfo = (PTOKEN_PRIMARY_GROUP)((PBYTE)pUserInfo + dwAlignUserSize);
  120. if (!InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION))
  121. {
  122. dwErr = GetLastError ();
  123. }
  124. if (!SetSecurityDescriptorDacl (pSd, TRUE, NULL, FALSE))
  125. {
  126. dwErr = GetLastError ();
  127. }
  128. if (!GetTokenInformation (hToken, TokenUser,
  129. pUserInfo, dwUserSize, &dwUserSize))
  130. {
  131. dwErr = GetLastError ();
  132. }
  133. if (!GetTokenInformation (hToken, TokenPrimaryGroup,
  134. pGroupInfo, dwGroupSize, &dwGroupSize))
  135. {
  136. dwErr = GetLastError ();
  137. }
  138. if (!SetSecurityDescriptorOwner (pSd, pUserInfo->User.Sid, FALSE))
  139. {
  140. dwErr = GetLastError ();
  141. }
  142. if (!SetSecurityDescriptorGroup (pSd, pGroupInfo->PrimaryGroup, FALSE))
  143. {
  144. dwErr = GetLastError ();
  145. }
  146. if (!dwErr)
  147. {
  148. // Build the DACL.
  149. //
  150. EXPLICIT_ACCESS ea;
  151. ea.grfAccessPermissions = COM_RIGHTS_EXECUTE;
  152. ea.grfAccessMode = SET_ACCESS;
  153. ea.grfInheritance = NO_INHERITANCE;
  154. ea.Trustee.pMultipleTrustee = NULL;
  155. ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  156. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  157. ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  158. ea.Trustee.ptstrName = (LPWSTR)&AUTHENTICATED_USERS_SID;
  159. dwErr = SetEntriesInAcl (1, &ea, NULL, &pAcl);
  160. if (!dwErr)
  161. {
  162. if (!SetSecurityDescriptorDacl(pSd, TRUE, pAcl, FALSE))
  163. {
  164. LocalFree(pAcl);
  165. dwErr = GetLastError();
  166. }
  167. }
  168. }
  169. // All is well, so assign the output parameters.
  170. //
  171. if (!dwErr)
  172. {
  173. *ppSd = pSd;
  174. *ppAcl = pAcl;
  175. }
  176. // Free our allocated buffer on failure.
  177. //
  178. else
  179. {
  180. MemFree (pvBuffer);
  181. }
  182. }
  183. else
  184. {
  185. dwErr = ERROR_OUTOFMEMORY;
  186. }
  187. finish:
  188. return dwErr;
  189. }
  190. BOOL
  191. InitializeSecurity (
  192. DWORD dwParam,
  193. DWORD dwAuthLevel,
  194. DWORD dwImpersonationLevel,
  195. DWORD dwAuthCapabilities
  196. )
  197. {
  198. HRESULT hr;
  199. PSECURITY_DESCRIPTOR pSd;
  200. PACL pAcl;
  201. IGlobalOptions *pIGLB;
  202. ASSERT (0 != dwParam);
  203. if (!DwInitializeSdFromThreadToken (&pSd, &pAcl))
  204. {
  205. hr = CoInitializeEx (NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
  206. if (SUCCEEDED(hr))
  207. {
  208. SVCHOST_LOG1(SECURITY,
  209. "Calling CoInitializeSecurity...(dwAuthCapabilities=0x%08x)\n",
  210. dwAuthCapabilities);
  211. hr = CoInitializeSecurity (
  212. pSd, -1, NULL, NULL,
  213. dwAuthLevel,
  214. dwImpersonationLevel,
  215. NULL,
  216. dwAuthCapabilities,
  217. NULL);
  218. if (FAILED(hr))
  219. {
  220. SVCHOST_LOG1(ERROR,
  221. "CoInitializeSecurity returned hr=0x%08x\n",
  222. hr);
  223. }
  224. }
  225. MemFree (pSd);
  226. LocalFree (pAcl);
  227. }
  228. else
  229. {
  230. hr = E_FAIL;
  231. }
  232. if (SUCCEEDED(hr))
  233. {
  234. //
  235. // Tell COM not to handle/mask fatal exceptions in server threads. If a service
  236. // that runs in-proc as a COM server faults, we want to know about it.
  237. //
  238. hr = CoCreateInstance(CLSID_GlobalOptions,
  239. NULL,
  240. CLSCTX_INPROC_SERVER,
  241. IID_IGlobalOptions,
  242. (void **) &pIGLB);
  243. if (SUCCEEDED(hr))
  244. {
  245. hr = pIGLB->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE);
  246. pIGLB->Release();
  247. }
  248. ASSERT(SUCCEEDED(hr));
  249. }
  250. return SUCCEEDED(hr);
  251. }