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.

377 lines
9.8 KiB

  1. //*************************************************************
  2. //
  3. // SID management functions.
  4. //
  5. // THESE FUNCTIONS ARE WINDOWS NT SPECIFIC!!!!!
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 1995
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include "uenv.h"
  13. /***************************************************************************\
  14. * GetSidString
  15. *
  16. * Allocates and returns a string representing the sid of the current user
  17. * The returned pointer should be freed using DeleteSidString().
  18. *
  19. * Returns a pointer to the string or NULL on failure.
  20. *
  21. * History:
  22. * 26-Aug-92 Davidc Created
  23. *
  24. \***************************************************************************/
  25. LPTSTR GetSidString(HANDLE UserToken)
  26. {
  27. NTSTATUS NtStatus;
  28. PSID UserSid;
  29. UNICODE_STRING UnicodeString;
  30. LPTSTR lpEnd;
  31. #ifndef UNICODE
  32. STRING String;
  33. #endif
  34. //
  35. // Get the user sid
  36. //
  37. UserSid = GetUserSid(UserToken);
  38. if (UserSid == NULL) {
  39. DebugMsg((DM_WARNING, TEXT("GetSidString: GetUserSid returned NULL")));
  40. return NULL;
  41. }
  42. //
  43. // Convert user SID to a string.
  44. //
  45. NtStatus = RtlConvertSidToUnicodeString(
  46. &UnicodeString,
  47. UserSid,
  48. (BOOLEAN)TRUE // Allocate
  49. );
  50. //
  51. // We're finished with the user sid
  52. //
  53. DeleteUserSid(UserSid);
  54. //
  55. // See if the conversion to a string worked
  56. //
  57. if (!NT_SUCCESS(NtStatus)) {
  58. DebugMsg((DM_WARNING, TEXT("GetSidString: RtlConvertSidToUnicodeString failed, status = 0x%x"),
  59. NtStatus));
  60. return NULL;
  61. }
  62. #ifdef UNICODE
  63. return(UnicodeString.Buffer);
  64. #else
  65. //
  66. // Convert the string to ansi
  67. //
  68. NtStatus = RtlUnicodeStringToAnsiString(&String, &UnicodeString, TRUE);
  69. RtlFreeUnicodeString(&UnicodeString);
  70. if (!NT_SUCCESS(NtStatus)) {
  71. DebugMsg((DM_WARNING, TEXT("GetSidString: RtlUnicodeStringToAnsiString failed, status = 0x%x"),
  72. status));
  73. return NULL;
  74. }
  75. return(String.Buffer);
  76. #endif
  77. }
  78. /***************************************************************************\
  79. * DeleteSidString
  80. *
  81. * Frees up a sid string previously returned by GetSidString()
  82. *
  83. * Returns nothing.
  84. *
  85. * History:
  86. * 26-Aug-92 Davidc Created
  87. *
  88. \***************************************************************************/
  89. VOID DeleteSidString(LPTSTR SidString)
  90. {
  91. #ifdef UNICODE
  92. UNICODE_STRING String;
  93. RtlInitUnicodeString(&String, SidString);
  94. RtlFreeUnicodeString(&String);
  95. #else
  96. ANSI_STRING String;
  97. RtlInitAnsiString(&String, SidString);
  98. RtlFreeAnsiString(&String);
  99. #endif
  100. }
  101. /***************************************************************************\
  102. * GetUserSid
  103. *
  104. * Allocs space for the user sid, fills it in and returns a pointer. Caller
  105. * The sid should be freed by calling DeleteUserSid.
  106. *
  107. * Note the sid returned is the user's real sid, not the per-logon sid.
  108. *
  109. * Returns pointer to sid or NULL on failure.
  110. *
  111. * History:
  112. * 26-Aug-92 Davidc Created.
  113. \***************************************************************************/
  114. PSID GetUserSid (HANDLE UserToken)
  115. {
  116. PTOKEN_USER pUser, pTemp;
  117. PSID pSid;
  118. DWORD BytesRequired = 200;
  119. NTSTATUS status;
  120. //
  121. // Allocate space for the user info
  122. //
  123. pUser = (PTOKEN_USER)LocalAlloc(LMEM_FIXED, BytesRequired);
  124. if (pUser == NULL) {
  125. DebugMsg((DM_WARNING, TEXT("GetUserSid: Failed to allocate %d bytes"),
  126. BytesRequired));
  127. return NULL;
  128. }
  129. //
  130. // Read in the UserInfo
  131. //
  132. status = NtQueryInformationToken(
  133. UserToken, // Handle
  134. TokenUser, // TokenInformationClass
  135. pUser, // TokenInformation
  136. BytesRequired, // TokenInformationLength
  137. &BytesRequired // ReturnLength
  138. );
  139. if (status == STATUS_BUFFER_TOO_SMALL) {
  140. //
  141. // Allocate a bigger buffer and try again.
  142. //
  143. pTemp = LocalReAlloc(pUser, BytesRequired, LMEM_MOVEABLE);
  144. if (pTemp == NULL) {
  145. DebugMsg((DM_WARNING, TEXT("GetUserSid: Failed to allocate %d bytes"),
  146. BytesRequired));
  147. LocalFree (pUser);
  148. return NULL;
  149. }
  150. pUser = pTemp;
  151. status = NtQueryInformationToken(
  152. UserToken, // Handle
  153. TokenUser, // TokenInformationClass
  154. pUser, // TokenInformation
  155. BytesRequired, // TokenInformationLength
  156. &BytesRequired // ReturnLength
  157. );
  158. }
  159. if (!NT_SUCCESS(status)) {
  160. DebugMsg((DM_WARNING, TEXT("GetUserSid: Failed to query user info from user token, status = 0x%x"),
  161. status));
  162. LocalFree(pUser);
  163. return NULL;
  164. }
  165. BytesRequired = RtlLengthSid(pUser->User.Sid);
  166. pSid = LocalAlloc(LMEM_FIXED, BytesRequired);
  167. if (pSid == NULL) {
  168. DebugMsg((DM_WARNING, TEXT("GetUserSid: Failed to allocate %d bytes"),
  169. BytesRequired));
  170. LocalFree(pUser);
  171. return NULL;
  172. }
  173. status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid);
  174. LocalFree(pUser);
  175. if (!NT_SUCCESS(status)) {
  176. DebugMsg((DM_WARNING, TEXT("GetUserSid: RtlCopySid Failed. status = %d"),
  177. status));
  178. LocalFree(pSid);
  179. pSid = NULL;
  180. }
  181. return pSid;
  182. }
  183. /***************************************************************************\
  184. * DeleteUserSid
  185. *
  186. * Deletes a user sid previously returned by GetUserSid()
  187. *
  188. * Returns nothing.
  189. *
  190. * History:
  191. * 26-Aug-92 Davidc Created
  192. *
  193. \***************************************************************************/
  194. VOID DeleteUserSid(PSID Sid)
  195. {
  196. LocalFree(Sid);
  197. }
  198. //+--------------------------------------------------------------------------
  199. //
  200. // Function: AllocateAndInitSidFromString
  201. //
  202. // Synopsis: given the string representation of a SID, this function
  203. // allocate and initializes a SID which the string represents
  204. // For more information on the string representation of SIDs
  205. // refer to ntseapi.h & ntrtl.h
  206. //
  207. // Arguments: [in] lpszSidStr : the string representation of the SID
  208. // [out] pSID : the actual SID structure created from the string
  209. //
  210. // Returns: STATUS_SUCCESS : if the sid structure was successfully created
  211. // or an error code based on errors that might occur
  212. //
  213. // History: 10/6/1998 RahulTh created
  214. // 02/25/2002 mingzhu using ConvertSidStringToSid()
  215. //
  216. //---------------------------------------------------------------------------
  217. NTSTATUS AllocateAndInitSidFromString (const WCHAR* lpszSidStr, PSID* ppSid)
  218. {
  219. if (ConvertStringSidToSid(lpszSidStr, ppSid))
  220. return STATUS_SUCCESS;
  221. else
  222. return GetLastError();
  223. }
  224. //*************************************************************
  225. //
  226. // GetDomainSidFromRid()
  227. //
  228. // Purpose: Given one domain sid, constructs another domain sid
  229. // by replacing the tail by the passed in Rid
  230. //
  231. // Parameters: pSid - Given Domain Sid
  232. // dwRid - Domain Rid
  233. // ppNewSid - Pointer to the New Sid
  234. //
  235. // Return: ERROR_SUCCESS on Success
  236. // FALSE if an error occurs
  237. //
  238. // Comments:
  239. // Sid returned must be freed using FreeSid.
  240. //
  241. // History: Date Author Comment
  242. // 6/6/95 ericflo Created
  243. //
  244. //*************************************************************
  245. NTSTATUS GetDomainSidFromDomainRid(PSID pSid, DWORD dwRid, PSID *ppNewSid)
  246. {
  247. PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority;
  248. // pointer to identifier authority
  249. BYTE nSubAuthorityCount, i; // count of subauthorities
  250. DWORD dwSubAuthority[8]={0,0,0,0,0,0,0,0}; // subauthority
  251. PUCHAR pSubAuthCount;
  252. DWORD *pdwSubAuth;
  253. NTSTATUS Status=ERROR_SUCCESS;
  254. DmAssert(IsValidSid(pSid));
  255. //
  256. // Will fail only if passed in sid is invalid and in the case
  257. // the returned value is undefined.
  258. //
  259. pIdentifierAuthority = RtlIdentifierAuthoritySid(pSid);
  260. //
  261. // get the count of subauthorities
  262. //
  263. pSubAuthCount = RtlSubAuthorityCountSid (pSid);
  264. if (!pSubAuthCount) {
  265. Status = ERROR_INVALID_SID;
  266. goto Exit;
  267. }
  268. nSubAuthorityCount = *pSubAuthCount;
  269. //
  270. // get each of the subauthorities
  271. //
  272. for (i = 0; i < (nSubAuthorityCount-1); i++) {
  273. pdwSubAuth = RtlSubAuthoritySid(pSid, i);
  274. if (!pdwSubAuth) {
  275. Status = ERROR_INVALID_SID;
  276. goto Exit;
  277. }
  278. dwSubAuthority[i] = *pdwSubAuth;
  279. }
  280. dwSubAuthority[i] = dwRid;
  281. //
  282. // Allocate a sid with these..
  283. //
  284. Status = RtlAllocateAndInitializeSid(
  285. pIdentifierAuthority,
  286. nSubAuthorityCount,
  287. dwSubAuthority[0],
  288. dwSubAuthority[1],
  289. dwSubAuthority[2],
  290. dwSubAuthority[3],
  291. dwSubAuthority[4],
  292. dwSubAuthority[5],
  293. dwSubAuthority[6],
  294. dwSubAuthority[7],
  295. ppNewSid
  296. );
  297. Exit:
  298. // Sid, All Done
  299. return Status;
  300. }