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.

343 lines
7.0 KiB

  1. //
  2. // Copyright (C) 2000, Microsoft Corporation
  3. //
  4. // File: gensecurity.c
  5. //
  6. // Contents:
  7. //
  8. // History:
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include "rpc.h"
  19. #include "rpcdce.h"
  20. #include <ole2.h>
  21. #include <activeds.h>
  22. #include <WinLdap.h>
  23. #include <NtLdap.h>
  24. #include <ntdsapi.h>
  25. #include "dfsheader.h"
  26. #include "dfsmisc.h"
  27. PVOID
  28. DfsAllocateSecurityData(ULONG Size )
  29. {
  30. PVOID pBuff = NULL;
  31. pBuff = (PVOID) malloc (Size);
  32. return pBuff;
  33. }
  34. VOID
  35. DfsDeallocateSecurityData(PVOID pPointer )
  36. {
  37. if(pPointer)
  38. {
  39. free (pPointer);
  40. }
  41. }
  42. DFSSTATUS
  43. AccessImpersonateCheckRpcClientEx(PSECURITY_DESCRIPTOR DfsAdminSecurityDesc,
  44. GENERIC_MAPPING * DfsAdminGenericMapping,
  45. DWORD DesiredAccess)
  46. {
  47. BOOL accessGranted = FALSE;
  48. DWORD grantedAccess = 0;
  49. HANDLE clientToken = NULL;
  50. DWORD privilegeSetSize = 0;
  51. DFSSTATUS dwErr = 0;
  52. DFSSTATUS RevertStatus = 0;
  53. BYTE privilegeSet[500]; // Large buffer
  54. if (RpcImpersonateClient(NULL) != ERROR_SUCCESS)
  55. {
  56. return ERROR_ACCESS_DENIED;
  57. }
  58. privilegeSetSize = sizeof(privilegeSet);
  59. if (OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY,
  60. TRUE, &clientToken))
  61. {
  62. if (AccessCheck(
  63. DfsAdminSecurityDesc,
  64. clientToken,
  65. DesiredAccess,
  66. DfsAdminGenericMapping,
  67. (PPRIVILEGE_SET) privilegeSet,
  68. &privilegeSetSize,
  69. &grantedAccess,
  70. &accessGranted) != TRUE)
  71. {
  72. accessGranted = FALSE; // paranoia
  73. //
  74. // No need to call GetLastError since we intend to return
  75. // ACCESS_DENIED regardless.
  76. //
  77. dwErr = GetLastError();
  78. }
  79. }
  80. RevertStatus = RpcRevertToSelf();
  81. if (clientToken != NULL)
  82. {
  83. CloseHandle( clientToken );
  84. }
  85. if( !accessGranted )
  86. {
  87. dwErr = ERROR_ACCESS_DENIED;
  88. }
  89. return dwErr;
  90. }
  91. VOID DumpSID(
  92. CHAR *pad,
  93. PSID sid_to_dump,
  94. ULONG Flag
  95. )
  96. {
  97. NTSTATUS ntstatus;
  98. UNICODE_STRING us;
  99. Flag;
  100. if (sid_to_dump)
  101. {
  102. WCHAR rgchName[256];
  103. DWORD cbName = sizeof(rgchName);
  104. WCHAR rgchDomain[256];
  105. DWORD cbDomain = sizeof(rgchDomain);
  106. SID_NAME_USE snu;
  107. ntstatus = RtlConvertSidToUnicodeString(&us, sid_to_dump, TRUE);
  108. if (NT_SUCCESS(ntstatus))
  109. {
  110. printf("%s%wZ", pad, &us);
  111. RtlFreeUnicodeString(&us);
  112. }
  113. else
  114. {
  115. printf("0x%08lx: Can't Convert SID to UnicodeString\n", ntstatus);
  116. }
  117. if (LookupAccountSid(NULL, sid_to_dump, rgchName, &cbName, rgchDomain, &cbDomain, &snu))
  118. {
  119. printf(" %ws\\%ws:", rgchDomain, rgchName);
  120. switch (snu)
  121. {
  122. case SidTypeUser:
  123. printf("User");
  124. break;
  125. case SidTypeGroup:
  126. printf("Group");
  127. break;
  128. case SidTypeDomain:
  129. printf("Domain");
  130. break;
  131. case SidTypeAlias:
  132. printf("Alias");
  133. break;
  134. case SidTypeWellKnownGroup:
  135. printf("Well Known Group");
  136. break;
  137. case SidTypeDeletedAccount:
  138. printf("Deleted Account");
  139. break;
  140. case SidTypeInvalid:
  141. printf("Invalid");
  142. break;
  143. case SidTypeUnknown:
  144. printf("Unknown");
  145. break;
  146. case SidTypeComputer:
  147. printf("Computer");
  148. break;
  149. default:
  150. printf("Unknown use: %d\n", snu);
  151. }
  152. }
  153. printf("\n");
  154. }
  155. else
  156. {
  157. printf("%s is NULL\n", pad);
  158. }
  159. }
  160. /*
  161. - DumpToken
  162. -
  163. * Purpose:
  164. * to dump a token
  165. *
  166. * Parameters:
  167. *
  168. * pad IN the string the prepend
  169. * htoken IN the token to dump
  170. */
  171. BOOL
  172. DumpToken(
  173. IN char *pad,
  174. IN HANDLE htoken)
  175. {
  176. BOOL fRet;
  177. DWORD dwError;
  178. DWORD dwLenNeeded;
  179. BYTE rgb[128];
  180. PTOKEN_USER ptu = (PTOKEN_USER) rgb;
  181. PTOKEN_USER ptuToFree = NULL;
  182. TOKEN_PRIMARY_GROUP *ptpg = (TOKEN_PRIMARY_GROUP*) rgb;
  183. TOKEN_PRIMARY_GROUP *ptpgToFree = NULL;
  184. TOKEN_GROUPS *ptg = (TOKEN_GROUPS*) rgb;
  185. TOKEN_GROUPS *ptgToFree = NULL;
  186. // dump token user
  187. fRet = GetTokenInformation(htoken, TokenUser, (void*) ptu, sizeof(rgb), &dwLenNeeded);
  188. if (!fRet)
  189. {
  190. dwError = GetLastError();
  191. if (dwError == ERROR_INSUFFICIENT_BUFFER)
  192. {
  193. ptuToFree = (PTOKEN_USER) malloc(dwLenNeeded);
  194. if (!ptuToFree)
  195. {
  196. printf("OOM\n");
  197. goto Error;
  198. }
  199. ptu = ptuToFree;
  200. fRet = GetTokenInformation(htoken, TokenUser, (void*) ptu, dwLenNeeded, &dwLenNeeded);
  201. if (!fRet)
  202. {
  203. dwError = GetLastError();
  204. }
  205. }
  206. }
  207. if (fRet)
  208. {
  209. printf("%s Token user is:\n", pad);
  210. DumpSID("", ptu->User.Sid, 0);
  211. }
  212. else
  213. {
  214. printf("%s 0x%08lx: Failed to get TokenUser\n", pad, dwError);
  215. }
  216. // dump token primary group
  217. fRet = GetTokenInformation(htoken, TokenPrimaryGroup, (void*) ptpg, sizeof(rgb), &dwLenNeeded);
  218. if (!fRet)
  219. {
  220. dwError = GetLastError();
  221. if (dwError == ERROR_INSUFFICIENT_BUFFER)
  222. {
  223. ptpgToFree = (TOKEN_PRIMARY_GROUP*) malloc(dwLenNeeded);
  224. if (!ptpgToFree)
  225. {
  226. printf("OOM\n");
  227. goto Error;
  228. }
  229. ptpg = ptpgToFree;
  230. fRet = GetTokenInformation(htoken, TokenPrimaryGroup, (void*) ptpg, dwLenNeeded, &dwLenNeeded);
  231. if (!fRet)
  232. {
  233. dwError = GetLastError();
  234. }
  235. }
  236. }
  237. if (fRet)
  238. {
  239. printf("%s Token's primary group is: \n", pad);
  240. DumpSID("", ptpg->PrimaryGroup, 0);
  241. }
  242. else
  243. {
  244. printf("%s 0x%08lx: Failed to get TokenPrimaryGroup\n", pad, dwError);
  245. }
  246. // dump token groups
  247. // TODO: add code to dump group attributes (in Text format)
  248. fRet = GetTokenInformation(htoken, TokenGroups, (void*) ptg, sizeof(rgb), &dwLenNeeded);
  249. if (!fRet)
  250. {
  251. dwError = GetLastError();
  252. if (dwError == ERROR_INSUFFICIENT_BUFFER)
  253. {
  254. ptgToFree = (TOKEN_GROUPS*) malloc(dwLenNeeded);
  255. if (!ptgToFree)
  256. {
  257. printf("OOM\n");
  258. goto Error;
  259. }
  260. ptg = ptgToFree;
  261. fRet = GetTokenInformation(htoken, TokenGroups, (void*) ptg, dwLenNeeded, &dwLenNeeded);
  262. if (!fRet)
  263. {
  264. dwError = GetLastError();
  265. }
  266. }
  267. }
  268. if (fRet)
  269. {
  270. UINT i;
  271. printf("%s token's groups are:\n", pad);
  272. for (i = 0; i < ptg->GroupCount; i++)
  273. {
  274. DumpSID("", ptg->Groups[i].Sid, 0);
  275. }
  276. }
  277. else
  278. {
  279. printf("%s 0x%08lx: Failed to get TokenGroups\n", pad, dwError);
  280. }
  281. // TODO: add code to dump other stuff later
  282. Cleanup:
  283. if (ptuToFree)
  284. {
  285. free(ptuToFree);
  286. }
  287. if (ptpgToFree)
  288. {
  289. free(ptpgToFree);
  290. }
  291. if (ptgToFree)
  292. {
  293. free(ptgToFree);
  294. }
  295. return fRet;
  296. Error:
  297. fRet = FALSE;
  298. goto Cleanup;
  299. }