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.

290 lines
4.8 KiB

  1. /*++
  2. Microsoft Confidential
  3. Copyright (c) 1992-1997 Microsoft Corporation
  4. All rights reserved
  5. Module Name:
  6. sid.c
  7. Abstract:
  8. SID management functions
  9. Author:
  10. (davidc) 26-Aug-1992
  11. --*/
  12. // NT base apis
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <ntdddisk.h>
  17. #include "sysdm.h"
  18. LPTSTR
  19. GetSidString(
  20. void
  21. )
  22. /*++
  23. Routine Description:
  24. Allocates and returns a string representing the sid of the current user
  25. The returned pointer should be freed using DeleteSidString().
  26. Arguments:
  27. None
  28. Return Value:
  29. Returns a pointer to the string or NULL on failure.
  30. --*/
  31. {
  32. NTSTATUS NtStatus;
  33. PSID UserSid;
  34. UNICODE_STRING UnicodeString;
  35. LPTSTR lpEnd;
  36. #ifndef UNICODE
  37. STRING String;
  38. #endif
  39. //
  40. // Get the user sid
  41. //
  42. UserSid = GetUserSid();
  43. if (UserSid == NULL) {
  44. return NULL;
  45. }
  46. //
  47. // Convert user SID to a string.
  48. //
  49. NtStatus = RtlConvertSidToUnicodeString(
  50. &UnicodeString,
  51. UserSid,
  52. (BOOLEAN)TRUE // Allocate
  53. );
  54. //
  55. // We're finished with the user sid
  56. //
  57. DeleteUserSid(UserSid);
  58. //
  59. // See if the conversion to a string worked
  60. //
  61. if (!NT_SUCCESS(NtStatus)) {
  62. return NULL;
  63. }
  64. #ifdef UNICODE
  65. return(UnicodeString.Buffer);
  66. #else
  67. //
  68. // Convert the string to ansi
  69. //
  70. NtStatus = RtlUnicodeStringToAnsiString(&String, &UnicodeString, TRUE);
  71. RtlFreeUnicodeString(&UnicodeString);
  72. if (!NT_SUCCESS(NtStatus)) {
  73. return NULL;
  74. }
  75. return(String.Buffer);
  76. #endif
  77. }
  78. VOID
  79. DeleteSidString(
  80. IN LPTSTR SidString
  81. )
  82. /*++
  83. Routine Description:
  84. Frees up a sid string previously returned by GetSidString()
  85. Arguments:
  86. SidString -
  87. Supplies string to free
  88. Return Value:
  89. None
  90. --*/
  91. {
  92. #ifdef UNICODE
  93. UNICODE_STRING String;
  94. RtlInitUnicodeString(&String, SidString);
  95. RtlFreeUnicodeString(&String);
  96. #else
  97. ANSI_STRING String;
  98. RtlInitAnsiString(&String, SidString);
  99. RtlFreeAnsiString(&String);
  100. #endif
  101. }
  102. PSID
  103. GetUserSid(
  104. void
  105. )
  106. /*++
  107. Routine Description:
  108. Allocs space for the user sid, fills it in and returns a pointer. Caller
  109. The sid should be freed by calling DeleteUserSid.
  110. Note the sid returned is the user's real sid, not the per-logon sid.
  111. Arguments:
  112. None
  113. Return Value:
  114. Returns pointer to sid or NULL on failure.
  115. --*/
  116. {
  117. PTOKEN_USER pUser, pTemp;
  118. PSID pSid;
  119. DWORD BytesRequired = 200;
  120. NTSTATUS status;
  121. HANDLE UserToken;
  122. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_READ, &UserToken)) {
  123. return NULL;
  124. }
  125. //
  126. // Allocate space for the user info
  127. //
  128. pUser = (PTOKEN_USER)LocalAlloc(LMEM_FIXED, BytesRequired);
  129. if (pUser == NULL) {
  130. CloseHandle (UserToken);
  131. return NULL;
  132. }
  133. //
  134. // Read in the UserInfo
  135. //
  136. status = NtQueryInformationToken(
  137. UserToken, // Handle
  138. TokenUser, // TokenInformationClass
  139. pUser, // TokenInformation
  140. BytesRequired, // TokenInformationLength
  141. &BytesRequired // ReturnLength
  142. );
  143. if (status == STATUS_BUFFER_TOO_SMALL) {
  144. //
  145. // Allocate a bigger buffer and try again.
  146. //
  147. pTemp = pUser;
  148. pUser = (PTOKEN_USER)LocalReAlloc(pUser, BytesRequired, LMEM_MOVEABLE);
  149. if (pUser == NULL) {
  150. LocalFree((HLOCAL) pTemp);
  151. CloseHandle (UserToken);
  152. return NULL;
  153. }
  154. status = NtQueryInformationToken(
  155. UserToken, // Handle
  156. TokenUser, // TokenInformationClass
  157. pUser, // TokenInformation
  158. BytesRequired, // TokenInformationLength
  159. &BytesRequired // ReturnLength
  160. );
  161. }
  162. if (!NT_SUCCESS(status)) {
  163. LocalFree(pUser);
  164. CloseHandle (UserToken);
  165. return NULL;
  166. }
  167. BytesRequired = RtlLengthSid(pUser->User.Sid);
  168. pSid = LocalAlloc(LMEM_FIXED, BytesRequired);
  169. if (pSid == NULL) {
  170. LocalFree(pUser);
  171. CloseHandle (UserToken);
  172. return NULL;
  173. }
  174. status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid);
  175. LocalFree(pUser);
  176. if (!NT_SUCCESS(status)) {
  177. LocalFree(pSid);
  178. pSid = NULL;
  179. }
  180. CloseHandle (UserToken);
  181. return pSid;
  182. }
  183. VOID
  184. DeleteUserSid(
  185. IN PSID Sid
  186. )
  187. /*++
  188. Routine Description:
  189. Deletes a user sid previously returned by GetUserSid()
  190. Arguments:
  191. Sid -
  192. Supplies sid to delete
  193. Return Value:
  194. None
  195. --*/
  196. {
  197. LocalFree(Sid);
  198. }