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.

569 lines
15 KiB

  1. /****************************************************************************
  2. PROGRAM: MYTOKEN.C
  3. PURPOSE: Contains routines that manipulate tokens
  4. ****************************************************************************/
  5. #include "PVIEWP.h"
  6. typedef PVOID *PPVOID;
  7. HANDLE OpenToken(
  8. HANDLE hMyToken,
  9. ACCESS_MASK DesiredAccess);
  10. BOOL CloseToken(
  11. HANDLE Token);
  12. BOOL GetTokenInfo(
  13. HANDLE Token,
  14. TOKEN_INFORMATION_CLASS TokenInformationClass,
  15. PPVOID pBuffer);
  16. BOOL SetTokenInfo(
  17. HANDLE Token,
  18. TOKEN_INFORMATION_CLASS TokenInformationClass,
  19. PVOID Buffer);
  20. BOOL FreeTokenInfo(
  21. PVOID Buffer);
  22. HANDLE AllocMyToken(VOID);
  23. BOOL ReadMyToken(HANDLE);
  24. BOOL WriteMyToken(HWND, HANDLE);
  25. BOOL FreeMyToken(HANDLE);
  26. PVOID AllocTokenInfo(HANDLE, TOKEN_INFORMATION_CLASS);
  27. /****************************************************************************
  28. FUNCTION: OpenMyToken
  29. PURPOSE: Opens the token of the specified process or thread.
  30. RETURNS : Handle to mytoken on success, or NULL on failure.
  31. ****************************************************************************/
  32. HANDLE OpenMyToken(
  33. HANDLE Token,
  34. LPWSTR Name
  35. )
  36. {
  37. PMYTOKEN pMyToken;
  38. HANDLE hMyToken;
  39. //
  40. // Build a MYTOKEN structure.
  41. hMyToken = AllocMyToken();
  42. if (hMyToken == NULL) {
  43. return(NULL);
  44. }
  45. pMyToken = (PMYTOKEN)hMyToken;
  46. pMyToken->Token = Token;
  47. pMyToken->Name = Alloc((lstrlenW(Name) + 1) * sizeof(WCHAR));
  48. if (pMyToken->Name == NULL) {
  49. Free(pMyToken);
  50. return(NULL);
  51. }
  52. lstrcpyW(pMyToken->Name, Name);
  53. if (!ReadMyToken(hMyToken)) {
  54. DbgPrint("PVIEW : Failed to read token info\n");
  55. Free(pMyToken->Name);
  56. Free(pMyToken);
  57. return(NULL);
  58. }
  59. return(hMyToken);
  60. }
  61. /****************************************************************************
  62. FUNCTION: ReadMyToken
  63. PURPOSE: Reads the token info and stores in mytoken structure
  64. RETURNS : TRUE on success, FALSE on failure
  65. ****************************************************************************/
  66. BOOL ReadMyToken(
  67. HANDLE hMyToken)
  68. {
  69. HANDLE Token;
  70. PMYTOKEN pMyToken = (PMYTOKEN)hMyToken;
  71. Token = OpenToken(hMyToken, TOKEN_QUERY);
  72. if (Token == NULL) {
  73. DbgPrint("PVIEW : Failed to open the token with TOKEN_QUERY access\n");
  74. return(FALSE);
  75. }
  76. if (!GetTokenInfo(Token, TokenStatistics, (PPVOID)&(pMyToken->TokenStats))) {
  77. DbgPrint("PVIEW : Failed to read token statistics from token\n");
  78. }
  79. if (!GetTokenInfo(Token, TokenGroups, (PPVOID)&(pMyToken->Groups))) {
  80. DbgPrint("PVIEW : Failed to read group info from token\n");
  81. }
  82. if (!GetTokenInfo(Token, TokenUser, (PPVOID)&(pMyToken->UserId))) {
  83. DbgPrint("PVIEW : Failed to read userid from token\n");
  84. }
  85. if (!GetTokenInfo(Token, TokenOwner, (PPVOID)&(pMyToken->DefaultOwner))) {
  86. DbgPrint("PVIEW : Failed to read default owner from token\n");
  87. }
  88. if (!GetTokenInfo(Token, TokenPrimaryGroup, (PPVOID)&(pMyToken->PrimaryGroup))) {
  89. DbgPrint("PVIEW : Failed to read primary group from token\n");
  90. }
  91. if (!GetTokenInfo(Token, TokenPrivileges, (PPVOID)&(pMyToken->Privileges))) {
  92. DbgPrint("PVIEW : Failed to read privilege info from token\n");
  93. }
  94. if ( !GetTokenInfo( Token, TokenRestrictedSids, (PPVOID) &(pMyToken->RestrictedSids) ) )
  95. {
  96. pMyToken->RestrictedSids = NULL ;
  97. }
  98. CloseToken(Token);
  99. return(TRUE);
  100. }
  101. /****************************************************************************
  102. FUNCTION: CloseMyToken
  103. PURPOSE: Closes the specified mytoken handle
  104. If fSaveChanges = TRUE, the token information is saved,
  105. otherwise it is discarded.
  106. RETURNS : TRUE on success, FALSE on failure.
  107. ****************************************************************************/
  108. BOOL CloseMyToken(
  109. HWND hDlg,
  110. HANDLE hMyToken,
  111. BOOL fSaveChanges)
  112. {
  113. if (fSaveChanges) {
  114. WriteMyToken(hDlg, hMyToken);
  115. }
  116. return FreeMyToken(hMyToken);
  117. }
  118. /****************************************************************************
  119. FUNCTION: AllocMyToken
  120. PURPOSE: Allocates space for mytoken structure.
  121. RETURNS : HANDLE to mytoken or NULL on failure.
  122. ****************************************************************************/
  123. HANDLE AllocMyToken(VOID)
  124. {
  125. PMYTOKEN pMyToken;
  126. pMyToken = (PMYTOKEN)Alloc(sizeof(MYTOKEN));
  127. return((HANDLE)pMyToken);
  128. }
  129. /****************************************************************************
  130. FUNCTION: FreeMyToken
  131. PURPOSE: Frees the memory allocated to mytoken structure.
  132. RETURNS : TRUE on success, FALSE on failure.
  133. ****************************************************************************/
  134. BOOL FreeMyToken(
  135. HANDLE hMyToken)
  136. {
  137. PMYTOKEN pMyToken = (PMYTOKEN)hMyToken;
  138. if (pMyToken->TokenStats != NULL) {
  139. FreeTokenInfo((PVOID)(pMyToken->TokenStats));
  140. }
  141. if (pMyToken->UserId != NULL) {
  142. FreeTokenInfo((PVOID)(pMyToken->UserId));
  143. }
  144. if (pMyToken->PrimaryGroup != NULL) {
  145. FreeTokenInfo((PVOID)(pMyToken->PrimaryGroup));
  146. }
  147. if (pMyToken->DefaultOwner != NULL) {
  148. FreeTokenInfo((PVOID)(pMyToken->DefaultOwner));
  149. }
  150. if (pMyToken->Groups != NULL) {
  151. FreeTokenInfo((PVOID)(pMyToken->Groups));
  152. }
  153. if (pMyToken->Privileges != NULL) {
  154. FreeTokenInfo((PVOID)(pMyToken->Privileges));
  155. }
  156. if (pMyToken->Name != NULL) {
  157. Free((PVOID)pMyToken->Name);
  158. }
  159. Free((PVOID)pMyToken);
  160. return(TRUE);
  161. }
  162. /****************************************************************************
  163. FUNCTION: WriteMyToken
  164. PURPOSE: Writes the token information out to the token
  165. RETURNS : TRUE on success, FALSE on failure.
  166. ****************************************************************************/
  167. BOOL WriteMyToken(
  168. HWND hDlg,
  169. HANDLE hMyToken)
  170. {
  171. PMYTOKEN pMyToken = (PMYTOKEN)hMyToken;
  172. HANDLE Token;
  173. //
  174. // Save default owner and primary group
  175. //
  176. Token = OpenToken(hMyToken, TOKEN_ADJUST_DEFAULT);
  177. if (Token == NULL) {
  178. DbgPrint("PVIEW: Failed to open token with TOKEN_ADJUST_DEFAULT access\n");
  179. MessageBox(hDlg, "Failed to open token with access required\nUnable to change default owner or primary group", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  180. } else {
  181. // Set default owner
  182. //
  183. if ((pMyToken->DefaultOwner != NULL) &&
  184. (!SetTokenInfo(Token, TokenOwner, (PVOID)(pMyToken->DefaultOwner)))) {
  185. MessageBox(hDlg, "Failed to set default owner", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  186. }
  187. // Set primary group
  188. //
  189. if ((pMyToken->PrimaryGroup != NULL) &&
  190. (!SetTokenInfo(Token, TokenPrimaryGroup, (PVOID)(pMyToken->PrimaryGroup)))) {
  191. MessageBox(hDlg, "Failed to set primary group", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  192. }
  193. CloseToken(Token);
  194. }
  195. //
  196. // Save group info
  197. //
  198. Token = OpenToken(hMyToken, TOKEN_ADJUST_GROUPS);
  199. if (Token == NULL) {
  200. DbgPrint("PVIEW: Failed to open token with TOKEN_ADJUST_GROUPS access\n");
  201. MessageBox(hDlg, "Failed to open token with access required\nUnable to change group settings", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  202. } else {
  203. if ((pMyToken->Groups != NULL) &&
  204. (!SetTokenInfo(Token, TokenGroups, (PVOID)(pMyToken->Groups)))) {
  205. MessageBox(hDlg, "Failed to change group settings", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  206. }
  207. CloseToken(Token);
  208. }
  209. //
  210. // Change privileges
  211. //
  212. Token = OpenToken(hMyToken, TOKEN_ADJUST_PRIVILEGES);
  213. if (Token == NULL) {
  214. DbgPrint("PVIEW: Failed to open token with TOKEN_ADJUST_PRIVILEGES access\n");
  215. MessageBox(hDlg, "Failed to open token with access required\nUnable to change privilege settings", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  216. } else {
  217. if ((pMyToken->Privileges != NULL) &&
  218. (!SetTokenInfo(Token, TokenPrivileges, (PVOID)(pMyToken->Privileges)))) {
  219. MessageBox(hDlg, "Failed to change privilege settings", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  220. }
  221. CloseToken(Token);
  222. }
  223. return(TRUE);
  224. }
  225. /****************************************************************************
  226. FUNCTION: OpenToken
  227. PURPOSE: Opens the token with the specified access
  228. RETURNS : Handle to token on success, or NULL on failure.
  229. ****************************************************************************/
  230. HANDLE OpenToken(
  231. HANDLE hMyToken,
  232. ACCESS_MASK DesiredAccess)
  233. {
  234. PMYTOKEN pMyToken = (PMYTOKEN)hMyToken;
  235. return(pMyToken->Token);
  236. }
  237. /****************************************************************************
  238. FUNCTION: CloseToken
  239. PURPOSE: Closes the specified token handle
  240. RETURNS : TRUE on success, FALSE on failure.
  241. ****************************************************************************/
  242. BOOL CloseToken(
  243. HANDLE Token)
  244. {
  245. return(TRUE);
  246. }
  247. /****************************************************************************
  248. FUNCTION: AllocTokenInfo
  249. PURPOSE: Allocates memory to hold the parameter that
  250. NTQueryInformationToken will return.
  251. Memory should be freed later using FreeTokenInfo
  252. RETURNS : Pointer to allocated memory or NULL on failure
  253. ****************************************************************************/
  254. PVOID AllocTokenInfo(
  255. HANDLE Token,
  256. TOKEN_INFORMATION_CLASS TokenInformationClass)
  257. {
  258. NTSTATUS Status;
  259. ULONG InfoLength;
  260. Status = NtQueryInformationToken(
  261. Token, // Handle
  262. TokenInformationClass, // TokenInformationClass
  263. NULL, // TokenInformation
  264. 0, // TokenInformationLength
  265. &InfoLength // ReturnLength
  266. );
  267. if (Status != STATUS_BUFFER_TOO_SMALL) {
  268. DbgPrint("PVIEW: NtQueryInformationToken did NOT return buffer_too_small, status = 0x%lx\n", Status);
  269. return(NULL);
  270. }
  271. return Alloc(InfoLength);
  272. }
  273. /****************************************************************************
  274. FUNCTION: FreeTokenInfo
  275. PURPOSE: Frees the memory previously allocated with AllocTokenInfo
  276. RETURNS : TRUE on success, otherwise FALSE
  277. ****************************************************************************/
  278. BOOL FreeTokenInfo(
  279. PVOID Buffer)
  280. {
  281. return(Free(Buffer));
  282. }
  283. /****************************************************************************
  284. FUNCTION: GetTokenInfo
  285. PURPOSE: Allocates a buffer and reads the specified data
  286. out of the token and into it.
  287. RETURNS : TRUE on success otherwise FALSE.
  288. ****************************************************************************/
  289. BOOL GetTokenInfo(
  290. HANDLE Token,
  291. TOKEN_INFORMATION_CLASS TokenInformationClass,
  292. PPVOID pBuffer)
  293. {
  294. NTSTATUS Status;
  295. ULONG BufferSize;
  296. ULONG InfoLength;
  297. PVOID Buffer;
  298. *pBuffer = NULL; // Prepare for failure
  299. Buffer = AllocTokenInfo(Token, TokenInformationClass);
  300. if (Buffer == NULL) {
  301. return(FALSE);
  302. }
  303. BufferSize = GetAllocSize(Buffer);
  304. Status = NtQueryInformationToken(
  305. Token, // Handle
  306. TokenInformationClass, // TokenInformationClass
  307. Buffer, // TokenInformation
  308. BufferSize, // TokenInformationLength
  309. &InfoLength // ReturnLength
  310. );
  311. if (!NT_SUCCESS(Status)) {
  312. DbgPrint("PVIEW: NtQueryInformationToken failed, status = 0x%lx\n", Status);
  313. FreeTokenInfo(Buffer);
  314. return(FALSE);
  315. }
  316. if (InfoLength > BufferSize) {
  317. DbgPrint("PVIEW: NtQueryInformationToken failed, DataSize > BufferSize");
  318. FreeTokenInfo(Buffer);
  319. return(FALSE);
  320. }
  321. *pBuffer = Buffer;
  322. return(TRUE);
  323. }
  324. /****************************************************************************
  325. FUNCTION: SetTokenInfo
  326. PURPOSE: Sets the specified information in the given token.
  327. RETURNS : TRUE on success otherwise FALSE.
  328. ****************************************************************************/
  329. BOOL SetTokenInfo(
  330. HANDLE Token,
  331. TOKEN_INFORMATION_CLASS TokenInformationClass,
  332. PVOID Buffer)
  333. {
  334. NTSTATUS Status;
  335. ULONG BufferSize;
  336. BufferSize = GetAllocSize(Buffer);
  337. switch (TokenInformationClass) {
  338. case TokenOwner:
  339. case TokenPrimaryGroup:
  340. case TokenDefaultDacl:
  341. Status = NtSetInformationToken(
  342. Token, // Handle
  343. TokenInformationClass, // TokenInformationClass
  344. Buffer, // TokenInformation
  345. BufferSize // TokenInformationLength
  346. );
  347. if (!NT_SUCCESS(Status)) {
  348. DbgPrint("PVIEW: NtSetInformationToken failed, info class = 0x%x, status = 0x%lx\n",
  349. TokenInformationClass, Status);
  350. return(FALSE);
  351. }
  352. break;
  353. case TokenGroups:
  354. Status = NtAdjustGroupsToken(
  355. Token, // Handle
  356. FALSE, // Reset to default
  357. (PTOKEN_GROUPS)Buffer, // New State
  358. BufferSize, // Buffer Length
  359. NULL, // Previous State
  360. NULL // Return Length
  361. );
  362. if (!NT_SUCCESS(Status)) {
  363. DbgPrint("PVIEW: NtAdjustGroupsToken failed, status = 0x%lx\n", Status);
  364. return(FALSE);
  365. }
  366. break;
  367. case TokenPrivileges:
  368. Status = NtAdjustPrivilegesToken(
  369. Token, // Handle
  370. FALSE, // Disable all privileges
  371. (PTOKEN_PRIVILEGES)Buffer, // New State
  372. BufferSize, // Buffer Length
  373. NULL, // Previous State
  374. NULL // Return Length
  375. );
  376. if (!NT_SUCCESS(Status)) {
  377. DbgPrint("PVIEW: NtAdjustPrivilegesToken failed, status = 0x%lx\n", Status);
  378. return(FALSE);
  379. }
  380. break;
  381. default:
  382. // Unrecognised information type
  383. DbgPrint("PVIEW: SetTokenInfo passed unrecognised infoclass, class = 0x%x\n", TokenInformationClass);
  384. return(FALSE);
  385. }
  386. return(TRUE);
  387. }