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.

530 lines
14 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1994
  6. //
  7. // File: policy.cxx
  8. //
  9. // Contents: SpmBuildCairoToken
  10. //
  11. //
  12. // History: 23-May-1994 MikeSw Created
  13. //
  14. //------------------------------------------------------------------------
  15. #include <lsapch.hxx>
  16. extern "C"
  17. {
  18. #include "adtp.h"
  19. }
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Function: LsapCreateToken
  23. //
  24. // Synopsis: Builds a token from the various pieces of information
  25. // generated during a logon.
  26. //
  27. // Effects:
  28. //
  29. // Arguments: pUserSid - sid of user to create token for
  30. // pTokenGroups - groups passed in to LogonUser or from PAC to
  31. // be put in token
  32. // pTokenPrivs - privileges from PAC to put in token
  33. // TokenType - type of token to create
  34. // pTokenSource - source of the token
  35. // pLogonId - Gets logon ID
  36. // phToken - Get handle to token
  37. //
  38. // Requires:
  39. //
  40. // Returns:
  41. //
  42. // Notes: TokenInformation is always freed, even on failure.
  43. //
  44. //
  45. //--------------------------------------------------------------------------
  46. NTSTATUS NTAPI
  47. LsapCreateToken(
  48. IN PLUID LogonId,
  49. IN PTOKEN_SOURCE TokenSource,
  50. IN SECURITY_LOGON_TYPE LogonType,
  51. IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  52. IN LSA_TOKEN_INFORMATION_TYPE InputTokenInformationType,
  53. IN PVOID InputTokenInformation,
  54. IN PTOKEN_GROUPS LocalGroups,
  55. IN PUNICODE_STRING AccountName,
  56. IN PUNICODE_STRING AuthorityName,
  57. IN PUNICODE_STRING WorkstationName,
  58. IN OPTIONAL PUNICODE_STRING ProfilePath,
  59. OUT PHANDLE Token,
  60. OUT PNTSTATUS SubStatus
  61. )
  62. {
  63. SECPKG_PRIMARY_CRED PrimaryCredential;
  64. ZeroMemory( &PrimaryCredential, sizeof(PrimaryCredential) );
  65. if( AccountName != NULL )
  66. {
  67. PrimaryCredential.DownlevelName = *AccountName;
  68. }
  69. if( AuthorityName != NULL )
  70. {
  71. PrimaryCredential.DomainName = *AuthorityName;
  72. }
  73. return LsapCreateTokenEx(
  74. LogonId,
  75. TokenSource,
  76. LogonType,
  77. ImpersonationLevel,
  78. InputTokenInformationType,
  79. InputTokenInformation,
  80. LocalGroups,
  81. WorkstationName,
  82. ProfilePath,
  83. &PrimaryCredential,
  84. SecSessionPrimaryCred,
  85. Token,
  86. SubStatus
  87. );
  88. }
  89. //+-------------------------------------------------------------------------
  90. //
  91. // Function: LsapCreateTokenEx
  92. //
  93. // Synopsis: Builds a token from the various pieces of information
  94. // generated during a logon.
  95. //
  96. // Effects:
  97. //
  98. // Arguments: pUserSid - sid of user to create token for
  99. // pTokenGroups - groups passed in to LogonUser or from PAC to
  100. // be put in token
  101. // pTokenPrivs - privileges from PAC to put in token
  102. // TokenType - type of token to create
  103. // pTokenSource - source of the token
  104. // pLogonId - Gets logon ID
  105. // phToken - Get handle to token
  106. //
  107. // Requires:
  108. //
  109. // Returns:
  110. //
  111. // Notes: TokenInformation is always freed, even on failure.
  112. //
  113. //
  114. //--------------------------------------------------------------------------
  115. NTSTATUS NTAPI
  116. LsapCreateTokenEx(
  117. IN PLUID LogonId,
  118. IN PTOKEN_SOURCE TokenSource,
  119. IN SECURITY_LOGON_TYPE LogonType,
  120. IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  121. IN LSA_TOKEN_INFORMATION_TYPE InputTokenInformationType,
  122. IN PVOID InputTokenInformation,
  123. IN PTOKEN_GROUPS LocalGroups,
  124. IN PUNICODE_STRING WorkstationName,
  125. IN PUNICODE_STRING ProfilePath,
  126. IN PVOID SessionInformation,
  127. IN SECPKG_SESSIONINFO_TYPE SessionInformationType,
  128. OUT PHANDLE Token,
  129. OUT PNTSTATUS SubStatus
  130. )
  131. {
  132. NTSTATUS Status;
  133. PPRIVILEGE_SET PrivilegesAssigned = NULL;
  134. PLSA_TOKEN_INFORMATION_V2 TokenInformationV2 = NULL;
  135. PLSA_TOKEN_INFORMATION_NULL TokenInformationNull = NULL;
  136. LSA_TOKEN_INFORMATION_TYPE OriginalTokenType = InputTokenInformationType;
  137. QUOTA_LIMITS QuotaLimits;
  138. PUNICODE_STRING NewAccountName = NULL;
  139. PUNICODE_STRING NewAuthorityName = NULL;
  140. PUNICODE_STRING NewProfilePath = NULL;
  141. UNICODE_STRING LocalAccountName = { 0 };
  142. UNICODE_STRING LocalAuthorityName = { 0 };
  143. UNICODE_STRING LocalProfilePath = { 0 };
  144. PSID NewUserSid = NULL;
  145. LSA_TOKEN_INFORMATION_TYPE TokenInformationType = InputTokenInformationType;
  146. PVOID TokenInformation = InputTokenInformation;
  147. PSECPKG_PRIMARY_CRED PrimaryCredential;
  148. PUNICODE_STRING AccountName;
  149. PUNICODE_STRING AuthorityName;
  150. *Token = NULL;
  151. *SubStatus = STATUS_SUCCESS;
  152. if( SessionInformationType != SecSessionPrimaryCred )
  153. {
  154. return STATUS_INVALID_PARAMETER;
  155. }
  156. PrimaryCredential = (PSECPKG_PRIMARY_CRED)SessionInformation;
  157. AccountName = &PrimaryCredential->DownlevelName;
  158. AuthorityName = &PrimaryCredential->DomainName;
  159. //
  160. // Pass the token information through the Local Security Policy
  161. // Filter/Augmentor. This may cause some or all of the token
  162. // information to be replaced/augmented.
  163. //
  164. Status = LsapAuUserLogonPolicyFilter(
  165. LogonType,
  166. &TokenInformationType,
  167. &TokenInformation,
  168. LocalGroups,
  169. &QuotaLimits,
  170. &PrivilegesAssigned,
  171. FALSE
  172. );
  173. if ( !NT_SUCCESS(Status) ) {
  174. goto Cleanup;
  175. }
  176. //
  177. // Check if we only allow admins to logon. We do allow null session
  178. // connections since they are severly restricted, though. Since the
  179. // token type may have been changed, we use the token type originally
  180. // returned by the package.
  181. //
  182. if (LsapAllowAdminLogonsOnly &&
  183. ((OriginalTokenType == LsaTokenInformationV1) ||
  184. (OriginalTokenType == LsaTokenInformationV2))&&
  185. !LsapSidPresentInGroups(
  186. ((PLSA_TOKEN_INFORMATION_V2) TokenInformation)->Groups,
  187. (SID *)LsapAliasAdminsSid)) {
  188. //
  189. // Set the status to be invalid workstation, since all accounts
  190. // except administrative ones are locked out for this
  191. // workstation.
  192. //
  193. *SubStatus = STATUS_INVALID_WORKSTATION;
  194. Status = STATUS_ACCOUNT_RESTRICTION;
  195. goto Cleanup;
  196. }
  197. //
  198. // Case on the token information returned (and subsequently massaged)
  199. // to create the correct kind of token.
  200. //
  201. switch (TokenInformationType) {
  202. case LsaTokenInformationNull:
  203. TokenInformationNull = (PLSA_TOKEN_INFORMATION_NULL) TokenInformation;
  204. //
  205. // The user hasn't logged on to any particular account.
  206. // An impersonation token with WORLD as owner
  207. // will be created.
  208. //
  209. Status = LsapCreateNullToken(
  210. LogonId,
  211. TokenSource,
  212. TokenInformationNull,
  213. Token
  214. );
  215. if ( !NT_SUCCESS(Status) ) {
  216. goto Cleanup;
  217. }
  218. break;
  219. case LsaTokenInformationV1:
  220. case LsaTokenInformationV2:
  221. TokenInformationV2 = (PLSA_TOKEN_INFORMATION_V2) TokenInformation;
  222. //
  223. // the type of token created depends upon the type of logon
  224. // being requested:
  225. //
  226. // InteractiveLogon => PrimaryToken
  227. // BatchLogon => PrimaryToken
  228. // NetworkLogon => ImpersonationToken
  229. //
  230. if (LogonType != Network) {
  231. //
  232. // Primary token
  233. //
  234. Status = LsapCreateV2Token(
  235. LogonId,
  236. TokenSource,
  237. TokenInformationV2,
  238. TokenPrimary,
  239. ImpersonationLevel,
  240. Token
  241. );
  242. if ( !NT_SUCCESS(Status) ) {
  243. goto Cleanup;
  244. }
  245. } else {
  246. //
  247. // Impersonation token
  248. //
  249. Status = LsapCreateV2Token(
  250. LogonId,
  251. TokenSource,
  252. TokenInformationV2,
  253. TokenImpersonation,
  254. ImpersonationLevel,
  255. Token
  256. );
  257. if ( !NT_SUCCESS(Status) ) {
  258. goto Cleanup;
  259. }
  260. }
  261. //
  262. // Copy out the User Sid
  263. //
  264. Status = LsapDuplicateSid( &NewUserSid, TokenInformationV2->User.User.Sid );
  265. if ( !NT_SUCCESS( Status )) {
  266. goto Cleanup;
  267. }
  268. break;
  269. }
  270. //
  271. // Audit special privilege assignment, if there were any
  272. //
  273. if ( PrivilegesAssigned != NULL ) {
  274. //
  275. // Examine the list of privileges being assigned, and
  276. // audit special privileges as appropriate.
  277. //
  278. LsapAdtAuditSpecialPrivileges( PrivilegesAssigned, *LogonId, NewUserSid );
  279. }
  280. NewAccountName = &LocalAccountName ;
  281. NewAuthorityName = &LocalAuthorityName ;
  282. //
  283. // If the original was a null session, set the user name & domain name
  284. // to be anonymous.
  285. //
  286. if (OriginalTokenType == LsaTokenInformationNull)
  287. {
  288. NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength);
  289. if (NewAccountName->Buffer == NULL)
  290. {
  291. Status = STATUS_INSUFFICIENT_RESOURCES;
  292. goto Cleanup;
  293. }
  294. NewAccountName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength;
  295. RtlCopyUnicodeString(
  296. NewAccountName,
  297. &WellKnownSids[LsapAnonymousSidIndex].Name
  298. );
  299. NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength);
  300. if (NewAuthorityName->Buffer == NULL)
  301. {
  302. Status = STATUS_INSUFFICIENT_RESOURCES;
  303. goto Cleanup;
  304. }
  305. NewAuthorityName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength;
  306. RtlCopyUnicodeString(
  307. NewAuthorityName,
  308. &WellKnownSids[LsapAnonymousSidIndex].DomainName
  309. );
  310. }
  311. else
  312. {
  313. NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AccountName->MaximumLength);
  314. if (NewAccountName->Buffer == NULL)
  315. {
  316. Status = STATUS_INSUFFICIENT_RESOURCES;
  317. goto Cleanup;
  318. }
  319. NewAccountName->MaximumLength = AccountName->MaximumLength;
  320. RtlCopyUnicodeString(
  321. NewAccountName,
  322. AccountName
  323. );
  324. NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AuthorityName->MaximumLength);
  325. if (NewAuthorityName->Buffer == NULL)
  326. {
  327. Status = STATUS_INSUFFICIENT_RESOURCES;
  328. goto Cleanup;
  329. }
  330. NewAuthorityName->MaximumLength = AuthorityName->MaximumLength;
  331. RtlCopyUnicodeString(
  332. NewAuthorityName,
  333. AuthorityName
  334. );
  335. if (ARGUMENT_PRESENT(ProfilePath) ) {
  336. NewProfilePath = &LocalProfilePath ;
  337. NewProfilePath->Buffer = (LPWSTR) LsapAllocateLsaHeap(ProfilePath->MaximumLength);
  338. if (NewProfilePath->Buffer == NULL)
  339. {
  340. Status = STATUS_INSUFFICIENT_RESOURCES;
  341. goto Cleanup;
  342. }
  343. NewProfilePath->MaximumLength = ProfilePath->MaximumLength;
  344. RtlCopyUnicodeString(
  345. NewProfilePath,
  346. ProfilePath
  347. );
  348. }
  349. }
  350. Status = LsapSetLogonSessionAccountInfo(
  351. LogonId,
  352. NewAccountName,
  353. NewAuthorityName,
  354. NewProfilePath,
  355. &NewUserSid,
  356. LogonType,
  357. PrimaryCredential
  358. );
  359. if (!NT_SUCCESS(Status))
  360. {
  361. goto Cleanup;
  362. }
  363. LocalAccountName.Buffer = NULL ;
  364. LocalAuthorityName.Buffer = NULL ;
  365. LocalProfilePath.Buffer = NULL ;
  366. //
  367. // Set the token on the session
  368. //
  369. Status = LsapSetSessionToken( *Token, LogonId );
  370. if ( !NT_SUCCESS(Status) ) {
  371. goto Cleanup;
  372. }
  373. Cleanup:
  374. //
  375. // Clean up on failure
  376. //
  377. if ( !NT_SUCCESS(Status) ) {
  378. //
  379. // If we successfully built the token,
  380. // free it.
  381. //
  382. if ( *Token != NULL ) {
  383. NtClose( *Token );
  384. *Token = NULL;
  385. }
  386. }
  387. //
  388. // Always free the token information because the policy filter
  389. // changes it.
  390. //
  391. switch (TokenInformationType) {
  392. case LsaTokenInformationNull:
  393. LsapFreeTokenInformationNull( (PLSA_TOKEN_INFORMATION_NULL) TokenInformation );
  394. break;
  395. case LsaTokenInformationV1:
  396. LsapFreeTokenInformationV1( (PLSA_TOKEN_INFORMATION_V1) TokenInformation );
  397. break;
  398. case LsaTokenInformationV2:
  399. LsapFreeTokenInformationV2( (PLSA_TOKEN_INFORMATION_V2) TokenInformation );
  400. break;
  401. }
  402. if ( LocalAccountName.Buffer != NULL )
  403. {
  404. LsapFreeLsaHeap( LocalAccountName.Buffer );
  405. }
  406. if ( LocalAuthorityName.Buffer != NULL )
  407. {
  408. LsapFreeLsaHeap( LocalAuthorityName.Buffer );
  409. }
  410. if ( LocalProfilePath.Buffer != NULL )
  411. {
  412. LsapFreeLsaHeap( LocalProfilePath.Buffer );
  413. }
  414. if (NewUserSid != NULL) {
  415. LsapFreeLsaHeap( NewUserSid );
  416. }
  417. if ( PrivilegesAssigned != NULL ) {
  418. MIDL_user_free( PrivilegesAssigned );
  419. }
  420. return(Status);
  421. }