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.

337 lines
8.0 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: lsautil.c
  3. *
  4. * Copyright (c) 1994, Microsoft Corporation
  5. *
  6. * Remote shell server main module
  7. *
  8. * History:
  9. * 05-19-94 DaveTh Created.
  10. \***************************************************************************/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <ntlsa.h>
  14. #include <windef.h>
  15. #include <nturtl.h>
  16. #include <winbase.h>
  17. #include "rcmdsrv.h"
  18. #define INITIAL_SIZE_REQUIRED 600
  19. DWORD
  20. CheckUserSystemAccess(
  21. HANDLE TokenHandle,
  22. ULONG DesiredSystemAccess,
  23. PBOOLEAN UserHasAccess
  24. )
  25. /*++
  26. Routine Description:
  27. This function determines whether or not the user whose token is passed
  28. has the interactive accesses desired on this machine.
  29. Arguments:
  30. TokenHandle - Handle of user's token.
  31. DesiredSystemAccess - Specifies desired access type(s).
  32. UserHasAccess - pointer to boolean returned - TRUE means that user
  33. has interactive access.
  34. Return Value:
  35. ERROR_SUCCESS in absence of errors. UserHasAccess is TRUE if all
  36. requested access types are permitted, otherwise FALSE. WIN32 errors
  37. are returned in error cases.
  38. --*/
  39. {
  40. DWORD Result;
  41. LPVOID LpTokenUserInformation = NULL;
  42. LPVOID LpTokenGroupInformation = NULL;
  43. DWORD SizeRequired, SizeProvided;
  44. LSA_HANDLE PolicyHandle = NULL;
  45. LSA_HANDLE AccountHandle = NULL;
  46. NTSTATUS NtStatus;
  47. OBJECT_ATTRIBUTES ObjectAttributes;
  48. POBJECT_ATTRIBUTES LpObjectAttributes;
  49. ULONG GrantedSystemAccess, SidSystemAccess;
  50. DWORD i;
  51. //
  52. // Access LSA policy database
  53. //
  54. LpObjectAttributes = &ObjectAttributes;
  55. InitializeObjectAttributes(
  56. LpObjectAttributes,
  57. NULL,
  58. 0,
  59. NULL,
  60. NULL);
  61. if (!NT_SUCCESS(NtStatus = LsaOpenPolicy(
  62. NULL, // Local system
  63. LpObjectAttributes,
  64. GENERIC_READ,
  65. &PolicyHandle))) {
  66. RcDbgPrint("Error opening policy database, error = %x\n", NtStatus);
  67. Result = RtlNtStatusToDosError(NtStatus);
  68. goto Failure;
  69. }
  70. //
  71. // Check groups, user - For each SID, open the account (if it exists).
  72. // If it doesn't exist, no failure, but no access (FALSE). If it
  73. // does exist, accumulate granted accesses in and compare to
  74. // requested mask. If all the bits of the mask have been set at any
  75. // point, UserHasAccess is set TRUE. Otherise, it is left FALSE.
  76. //
  77. *UserHasAccess = FALSE;
  78. GrantedSystemAccess = 0;
  79. //
  80. // Get list of SIDs of groups of which user is a member
  81. //
  82. if ((LpTokenGroupInformation = Alloc(INITIAL_SIZE_REQUIRED)) == NULL) {
  83. Result = GetLastError();
  84. goto Failure;
  85. }
  86. if (!GetTokenInformation (
  87. TokenHandle,
  88. TokenGroups,
  89. LpTokenGroupInformation,
  90. INITIAL_SIZE_REQUIRED,
  91. &SizeRequired)) {
  92. Result = GetLastError();
  93. if ( (Result == ERROR_MORE_DATA) || (Result == ERROR_INSUFFICIENT_BUFFER) ) {
  94. Free(LpTokenGroupInformation);
  95. if ((LpTokenGroupInformation = Alloc(SizeRequired)) == NULL) {
  96. Result = GetLastError();
  97. goto Failure;
  98. }
  99. SizeProvided = SizeRequired;
  100. if (!GetTokenInformation (
  101. TokenHandle,
  102. TokenGroups,
  103. LpTokenGroupInformation,
  104. SizeProvided,
  105. &SizeRequired)) {
  106. Result=GetLastError();
  107. RcDbgPrint("Error accessing group SIDs, error = %d\n", Result);
  108. goto Failure;
  109. }
  110. } else {
  111. RcDbgPrint("Error accessing group SIDs, error = %d\n", Result);
  112. goto Failure;
  113. }
  114. }
  115. //
  116. // Check for each group that user is a member of since groups
  117. // are most likely source of permitted access. Permitted access types
  118. // are cumulative.
  119. //
  120. for (i=0; i< ((PTOKEN_GROUPS)LpTokenGroupInformation)->GroupCount; i++) {
  121. if (NT_SUCCESS(NtStatus = LsaOpenAccount(
  122. PolicyHandle,
  123. ((PTOKEN_GROUPS)LpTokenGroupInformation)->Groups[i].Sid,
  124. GENERIC_READ,
  125. &AccountHandle))) {
  126. //
  127. // found account - accumulate and check accesses
  128. //
  129. if (!NT_SUCCESS(NtStatus = LsaGetSystemAccessAccount (
  130. AccountHandle,
  131. &SidSystemAccess))) {
  132. RcDbgPrint("Error getting group account access, error = %x\n", NtStatus);
  133. Result = RtlNtStatusToDosError(NtStatus);
  134. goto Failure;
  135. } else {
  136. //
  137. // Got system access - don't need account handle anymore
  138. //
  139. if (NT_SUCCESS(NtStatus = LsaClose(AccountHandle))) {
  140. AccountHandle = NULL;
  141. } else {
  142. RcDbgPrint("Error closing account handle, error = %x\n", NtStatus);
  143. Result = RtlNtStatusToDosError(NtStatus);
  144. goto Failure;
  145. }
  146. GrantedSystemAccess |= SidSystemAccess;;
  147. if ((GrantedSystemAccess & DesiredSystemAccess) == DesiredSystemAccess) {
  148. *UserHasAccess = TRUE;
  149. goto Success;
  150. }
  151. }
  152. } else if (NtStatus != STATUS_OBJECT_NAME_NOT_FOUND) {
  153. RcDbgPrint("Error opening group account, error = %x\n", NtStatus);
  154. Result = RtlNtStatusToDosError(NtStatus);
  155. goto Failure;
  156. }
  157. }
  158. //
  159. // Get user SID
  160. //
  161. if ((LpTokenUserInformation = Alloc(INITIAL_SIZE_REQUIRED)) == NULL) {
  162. Result = GetLastError();
  163. goto Failure;
  164. }
  165. if (!GetTokenInformation (
  166. TokenHandle,
  167. TokenUser,
  168. LpTokenUserInformation,
  169. INITIAL_SIZE_REQUIRED,
  170. &SizeRequired)) {
  171. Result = GetLastError();
  172. if (Result == ERROR_MORE_DATA) { // Not enough - alloc and redo
  173. Free(LpTokenUserInformation);
  174. if ((LpTokenUserInformation = Alloc(SizeRequired)) == NULL) {
  175. Result = GetLastError();
  176. goto Failure;
  177. }
  178. SizeProvided = SizeRequired;
  179. if (!GetTokenInformation (
  180. TokenHandle,
  181. TokenUser,
  182. LpTokenUserInformation,
  183. SizeProvided,
  184. &SizeRequired)) {
  185. RcDbgPrint("Error accessing user SID, error = %d\n", Result);
  186. Result=GetLastError();
  187. goto Failure;
  188. }
  189. } else {
  190. RcDbgPrint("Error accessing user SID, error = %d\n", Result);
  191. goto Failure;
  192. }
  193. }
  194. //
  195. // Now, check user account. If present, check access and return
  196. // if requested access is allowed. If not allowed, go on to check groups.
  197. // If account doesn't exist, go on to check groups.
  198. //
  199. if (NT_SUCCESS(NtStatus = LsaOpenAccount(
  200. PolicyHandle,
  201. ((PTOKEN_USER)LpTokenUserInformation)->User.Sid,
  202. GENERIC_READ,
  203. &AccountHandle))) {
  204. //
  205. // found account - check accesses
  206. //
  207. if (!NT_SUCCESS(NtStatus = LsaGetSystemAccessAccount (
  208. AccountHandle,
  209. &GrantedSystemAccess))) {
  210. RcDbgPrint("Error getting group account access, error = %x\n", NtStatus);
  211. Result = RtlNtStatusToDosError(NtStatus);
  212. goto Failure;
  213. } else {
  214. GrantedSystemAccess |= SidSystemAccess;;
  215. if ((GrantedSystemAccess & DesiredSystemAccess) == DesiredSystemAccess) {
  216. *UserHasAccess = TRUE;
  217. goto Success;
  218. }
  219. }
  220. } else if (NtStatus != STATUS_OBJECT_NAME_NOT_FOUND) {
  221. RcDbgPrint("Error opening user account, error = %x\n", NtStatus);
  222. Result = RtlNtStatusToDosError(NtStatus);
  223. goto Failure;
  224. }
  225. //
  226. // Success - Jump here if access granted, fall through here on no error
  227. //
  228. Success:
  229. Result = ERROR_SUCCESS;
  230. //
  231. // General failure and success exit - frees memory, closes handles
  232. //
  233. Failure:
  234. if (LpTokenGroupInformation != NULL) {
  235. Free(LpTokenGroupInformation);
  236. }
  237. if (LpTokenUserInformation != NULL) {
  238. Free(LpTokenGroupInformation);
  239. }
  240. if ((PolicyHandle != NULL) &&
  241. (!NT_SUCCESS(NtStatus = LsaClose(PolicyHandle)))) {
  242. RcDbgPrint("Error closing policy handle at exit, error = %x\n", NtStatus);
  243. Result = RtlNtStatusToDosError(NtStatus);
  244. }
  245. if ((AccountHandle != NULL) &&
  246. (!NT_SUCCESS(NtStatus = LsaClose(AccountHandle)))) {
  247. RcDbgPrint("Error closing account handle at exit, error = %x\n", NtStatus);
  248. Result = RtlNtStatusToDosError(NtStatus);
  249. }
  250. return(Result);
  251. }