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.

456 lines
11 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include "common.h"
  4. #include "security.h"
  5. #include "debugout.h"
  6. /*
  7. * GetTokenHandle
  8. */
  9. BOOL GetTokenHandle(
  10. PHANDLE pTokenHandle )
  11. {
  12. if (OpenThreadToken( GetCurrentThread(), TOKEN_READ, FALSE, pTokenHandle))
  13. return TRUE;
  14. if (GetLastError() != ERROR_NO_TOKEN)
  15. return FALSE;
  16. if (OpenProcessToken( GetCurrentProcess(), TOKEN_READ, pTokenHandle))
  17. return TRUE;
  18. return FALSE;
  19. }
  20. /*
  21. * MakeLocalOnlySD
  22. *
  23. * Purpose: Generate a self-relative SD whose ACL contains only an
  24. * entry for LocalSystem/GENERIC_ALL access. This SD will be used
  25. * in calls to CreateFile() for clipbook page files.
  26. *
  27. * Parameters: None
  28. *
  29. * Returns: Pointer to the security descriptor. This pointer may be freed.
  30. * Returns NULL on failure.
  31. */
  32. PSECURITY_DESCRIPTOR MakeLocalOnlySD (void)
  33. {
  34. PSECURITY_DESCRIPTOR pSD;
  35. PSECURITY_DESCRIPTOR pSDSelfRel = NULL;
  36. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  37. PSID sidLocal;
  38. PACL Acl;
  39. DWORD dwAclSize;
  40. if (AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  41. 0, 0, 0, 0, 0, 0, 0, &sidLocal))
  42. {
  43. if (InitializeSecurityDescriptor(&pSD, SECURITY_DESCRIPTOR_REVISION))
  44. {
  45. // Allocate space for DACL with "System Full Control" access
  46. dwAclSize = sizeof(ACL)+ GetLengthSid(sidLocal) +
  47. sizeof(ACCESS_ALLOWED_ACE) + 42; // 42==fudge factor
  48. if (Acl = (PACL)GlobalAlloc(GPTR, dwAclSize))
  49. {
  50. if (InitializeAcl(Acl, dwAclSize, ACL_REVISION))
  51. {
  52. // LocalSystem gets all access, nobody else gets any.
  53. if (AddAccessAllowedAce(Acl, ACL_REVISION,
  54. GENERIC_ALL, sidLocal))
  55. {
  56. if (SetSecurityDescriptorDacl(pSD, TRUE, Acl, TRUE))
  57. {
  58. DWORD dwSelfRelLen;
  59. dwSelfRelLen = GetSecurityDescriptorLength(pSD);
  60. pSDSelfRel = GlobalAlloc(GPTR, dwSelfRelLen);
  61. if (pSDSelfRel)
  62. {
  63. if (!MakeSelfRelativeSD(pSD, pSDSelfRel, &dwSelfRelLen))
  64. {
  65. GlobalFree((HANDLE)pSDSelfRel);
  66. pSDSelfRel = NULL;
  67. }
  68. }
  69. }
  70. }
  71. }
  72. GlobalFree((HANDLE)Acl);
  73. }
  74. }
  75. FreeSid(sidLocal);
  76. }
  77. return(pSDSelfRel);
  78. }
  79. /*
  80. * CurrentUserOnlySD
  81. *
  82. * Purpose: Create a security descriptor containing only a single
  83. * DACL entry-- one to allow the user whose context we are running
  84. * in GENERIC_ALL access.
  85. *
  86. * Parameters: None.
  87. *
  88. * Returns: A pointer to the security descriptor described above,
  89. * or NULL on failure.
  90. */
  91. PSECURITY_DESCRIPTOR CurrentUserOnlySD (void)
  92. {
  93. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  94. SECURITY_DESCRIPTOR aSD;
  95. PSECURITY_DESCRIPTOR pSD = NULL;
  96. BOOL OK;
  97. PACL TmpAcl;
  98. PACCESS_ALLOWED_ACE TmpAce;
  99. DWORD lSD;
  100. LONG DaclLength;
  101. DWORD lTokenInfo;
  102. HANDLE hClientToken;
  103. TOKEN_USER *pUserTokenInfo;
  104. if (!InitializeSecurityDescriptor(&aSD, SECURITY_DESCRIPTOR_REVISION)
  105. || GetTokenHandle(&hClientToken))
  106. {
  107. PERROR(TEXT("Couldn't get token handle or InitSD bad \r\n"));
  108. return NULL;
  109. }
  110. // See if the token info fits in 50 bytes. If it does, fine.
  111. // If not, realloc to proper size and get the token info.
  112. pUserTokenInfo = (TOKEN_USER *)LocalAlloc( LMEM_FIXED, 50 );
  113. if (pUserTokenInfo && !GetTokenInformation( hClientToken, TokenUser,
  114. (LPVOID) pUserTokenInfo, 50, &lTokenInfo ) )
  115. {
  116. LocalFree( pUserTokenInfo );
  117. pUserTokenInfo = (TOKEN_USER *)LocalAlloc( LMEM_FIXED, lTokenInfo );
  118. if (!GetTokenInformation( hClientToken, TokenUser,
  119. (LPVOID) pUserTokenInfo, lTokenInfo, &lTokenInfo ) )
  120. {
  121. LocalFree( pUserTokenInfo );
  122. pUserTokenInfo = NULL;
  123. }
  124. }
  125. if (!pUserTokenInfo)
  126. {
  127. PERROR(TEXT("Couldn't get usertokeninfo\r\n"));
  128. }
  129. else
  130. {
  131. // Figure out how big a Dacl we'll need for just me to be on it.
  132. DaclLength = (DWORD)sizeof(ACL) +
  133. GetLengthSid( pUserTokenInfo->User.Sid ) +
  134. (DWORD)sizeof( ACCESS_ALLOWED_ACE );
  135. if (!(TmpAcl = (PACL)LocalAlloc(LMEM_FIXED, DaclLength )))
  136. {
  137. PERROR(TEXT("LocalAllof for Acl fail\r\n"));
  138. }
  139. else
  140. {
  141. if (!InitializeAcl( TmpAcl, DaclLength, ACL_REVISION ))
  142. {
  143. PERROR(TEXT("InitializeAcl fail\r\n"));
  144. }
  145. else if (!AddAccessAllowedAce( TmpAcl, ACL_REVISION,
  146. GENERIC_ALL, pUserTokenInfo->User.Sid ))
  147. {
  148. PERROR(TEXT("AddAccessAllowedAce fail\r\n"));
  149. }
  150. else if (!GetAce( TmpAcl, 0, (LPVOID *)&TmpAce))
  151. {
  152. PERROR("GetAce error %d", GetLastError());
  153. }
  154. else
  155. {
  156. TmpAce->Header.AceFlags = 0;
  157. OK = SetSecurityDescriptorDacl(&aSD, TRUE, TmpAcl, FALSE);
  158. lSD = GetSecurityDescriptorLength( &aSD);
  159. if (pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, lSD))
  160. {
  161. MakeSelfRelativeSD( &aSD, pSD, &lSD);
  162. if( IsValidSecurityDescriptor( pSD ) )
  163. {
  164. LocalFree(pSD);
  165. pSD = NULL;
  166. }
  167. else
  168. {
  169. PERROR(TEXT("Failed creating self-relative SD (%d)."),
  170. GetLastError());
  171. }
  172. }
  173. else
  174. {
  175. PERROR(TEXT("LocalAlloc for pSD fail\r\n"));
  176. }
  177. }
  178. LocalFree((HANDLE)TmpAcl);
  179. }
  180. LocalFree((HANDLE)pUserTokenInfo);
  181. }
  182. CloseHandle(hClientToken);
  183. return pSD;
  184. }
  185. #ifdef DEBUG
  186. /*
  187. * HexDumpBytes
  188. */
  189. void HexDumpBytes(
  190. char *pv,
  191. unsigned cb)
  192. {
  193. char achHex[]="0123456789ABCDEF";
  194. char achOut[80];
  195. unsigned iOut;
  196. iOut = 0;
  197. while (cb)
  198. {
  199. if (iOut >= 78)
  200. {
  201. PINFO(achOut);
  202. iOut = 0;
  203. }
  204. achOut[iOut++] = achHex[(*pv >> 4) & 0x0f];
  205. achOut[iOut++] = achHex[*pv++ & 0x0f];
  206. achOut[iOut] = '\0';
  207. cb--;
  208. }
  209. if (iOut)
  210. {
  211. PINFO(achOut);
  212. }
  213. }
  214. /*
  215. * PrintSid
  216. */
  217. void PrintSid(
  218. PSID sid)
  219. {
  220. DWORD cSubAuth;
  221. DWORD i;
  222. PINFO(TEXT("\r\nSID: "));
  223. if (sid)
  224. {
  225. HexDumpBytes((char *)GetSidIdentifierAuthority(sid), sizeof(SID_IDENTIFIER_AUTHORITY));
  226. SetLastError(0);
  227. cSubAuth = *GetSidSubAuthorityCount(sid);
  228. if (GetLastError())
  229. {
  230. PINFO(TEXT("Invalid SID\r\n"));
  231. }
  232. else
  233. {
  234. for (i = 0;i < cSubAuth; i++)
  235. {
  236. PINFO(TEXT("-"));
  237. HexDumpBytes((char *)GetSidSubAuthority(sid, i), sizeof(DWORD));
  238. }
  239. PINFO(TEXT("\r\n"));
  240. }
  241. }
  242. else
  243. {
  244. PINFO(TEXT("NULL SID\r\n"));
  245. }
  246. }
  247. /*
  248. * PrintAcl
  249. *
  250. * Purpose: Print out the entries in an access-control list.
  251. */
  252. void PrintAcl(
  253. PACL pacl)
  254. {
  255. ACL_SIZE_INFORMATION aclsi;
  256. ACCESS_ALLOWED_ACE *pace;
  257. unsigned i;
  258. if (pacl)
  259. {
  260. if (GetAclInformation (pacl, &aclsi, sizeof(aclsi), AclSizeInformation))
  261. {
  262. for (i = 0;i < aclsi.AceCount;i++)
  263. {
  264. GetAce(pacl, i, &pace);
  265. PINFO(TEXT("Type(%x) Flags(%x) Access(%lx)\r\nSID:"),
  266. (int)pace->Header.AceType,
  267. (int)pace->Header.AceFlags,
  268. pace->Mask);
  269. PrintSid((PSID)&(pace->SidStart));
  270. }
  271. }
  272. }
  273. else
  274. {
  275. PINFO(TEXT("NULL PACL\r\n"));
  276. }
  277. }
  278. /*
  279. * PrintSD
  280. */
  281. void PrintSD(
  282. PSECURITY_DESCRIPTOR pSD)
  283. {
  284. DWORD dwRev;
  285. WORD wSDC;
  286. BOOL fDefault, fAcl;
  287. PACL pacl;
  288. PSID sid;
  289. if (NULL == pSD)
  290. {
  291. PINFO(TEXT("NULL sd\r\n"));
  292. return;
  293. }
  294. if (!IsValidSecurityDescriptor(pSD))
  295. {
  296. PINFO(TEXT("Bad SD %p"), pSD);
  297. return;
  298. }
  299. // Drop control info and revision
  300. if (GetSecurityDescriptorControl(pSD, &wSDC, &dwRev))
  301. {
  302. PINFO(TEXT("SD - Length: [%ld] Control: [%x] [%lx]\r\nGroup:"),
  303. GetSecurityDescriptorLength(pSD), wSDC, dwRev);
  304. }
  305. else
  306. {
  307. PINFO(TEXT("Couldn't get control\r\nGroup"));
  308. }
  309. // Show group and owner
  310. if (GetSecurityDescriptorGroup(pSD, &sid, &fDefault) &&
  311. sid &&
  312. IsValidSid(sid))
  313. {
  314. PrintSid(sid);
  315. PINFO(TEXT(" %s default.\r\nOwner:"), fDefault ? TEXT(" ") : TEXT("Not"));
  316. }
  317. else
  318. {
  319. PINFO(TEXT("Couldn't get group\r\n"));
  320. }
  321. if (GetSecurityDescriptorOwner(pSD, &sid, &fDefault) &&
  322. sid &&
  323. IsValidSid(sid))
  324. {
  325. PrintSid(sid);
  326. PINFO(TEXT(" %s default.\r\n"), fDefault ? TEXT(" ") : TEXT("Not"));
  327. }
  328. else
  329. {
  330. PINFO(TEXT("Couldn't get owner\r\n"));
  331. }
  332. // Print DACL and SACL
  333. if (GetSecurityDescriptorDacl(pSD, &fAcl, &pacl, &fDefault))
  334. {
  335. PINFO(TEXT("DACL: %s %s\r\n"), fAcl ? "Yes" : "No",
  336. fDefault ? "Default" : " ");
  337. if (fAcl)
  338. {
  339. if (pacl && IsValidAcl(pacl))
  340. {
  341. PrintAcl(pacl);
  342. }
  343. else
  344. {
  345. PINFO(TEXT("Invalid Acl %p\r\n"), pacl);
  346. }
  347. }
  348. }
  349. else
  350. {
  351. PINFO(TEXT("Couldn't get DACL\r\n"));
  352. }
  353. if (GetSecurityDescriptorSacl(pSD, &fAcl, &pacl, &fDefault))
  354. {
  355. PINFO(TEXT("SACL: %s %s\r\n"), fAcl ? "Yes" : "No", fDefault ? "Default" : " ");
  356. if (fAcl)
  357. {
  358. if (pacl && IsValidAcl(pacl))
  359. {
  360. PrintAcl(pacl);
  361. }
  362. else
  363. {
  364. PINFO(TEXT("Invalid ACL %p\r\n"), pacl);
  365. }
  366. }
  367. }
  368. else
  369. {
  370. PINFO(TEXT("Couldn't get SACL\r\n"));
  371. }
  372. }
  373. #else
  374. #define PrintSid(x)
  375. #define PrintSD(x)
  376. #endif