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.

529 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. );
  172. if ( !NT_SUCCESS(Status) ) {
  173. goto Cleanup;
  174. }
  175. //
  176. // Check if we only allow admins to logon. We do allow null session
  177. // connections since they are severly restricted, though. Since the
  178. // token type may have been changed, we use the token type originally
  179. // returned by the package.
  180. //
  181. if (LsapAllowAdminLogonsOnly &&
  182. ((OriginalTokenType == LsaTokenInformationV1) ||
  183. (OriginalTokenType == LsaTokenInformationV2))&&
  184. !LsapSidPresentInGroups(
  185. ((PLSA_TOKEN_INFORMATION_V2) TokenInformation)->Groups,
  186. (SID *)LsapAliasAdminsSid)) {
  187. //
  188. // Set the status to be invalid workstation, since all accounts
  189. // except administrative ones are locked out for this
  190. // workstation.
  191. //
  192. *SubStatus = STATUS_INVALID_WORKSTATION;
  193. Status = STATUS_ACCOUNT_RESTRICTION;
  194. goto Cleanup;
  195. }
  196. //
  197. // Case on the token information returned (and subsequently massaged)
  198. // to create the correct kind of token.
  199. //
  200. switch (TokenInformationType) {
  201. case LsaTokenInformationNull:
  202. TokenInformationNull = (PLSA_TOKEN_INFORMATION_NULL) TokenInformation;
  203. //
  204. // The user hasn't logged on to any particular account.
  205. // An impersonation token with WORLD as owner
  206. // will be created.
  207. //
  208. Status = LsapCreateNullToken(
  209. LogonId,
  210. TokenSource,
  211. TokenInformationNull,
  212. Token
  213. );
  214. if ( !NT_SUCCESS(Status) ) {
  215. goto Cleanup;
  216. }
  217. break;
  218. case LsaTokenInformationV1:
  219. case LsaTokenInformationV2:
  220. TokenInformationV2 = (PLSA_TOKEN_INFORMATION_V2) TokenInformation;
  221. //
  222. // the type of token created depends upon the type of logon
  223. // being requested:
  224. //
  225. // InteractiveLogon => PrimaryToken
  226. // BatchLogon => PrimaryToken
  227. // NetworkLogon => ImpersonationToken
  228. //
  229. if (LogonType != Network) {
  230. //
  231. // Primary token
  232. //
  233. Status = LsapCreateV2Token(
  234. LogonId,
  235. TokenSource,
  236. TokenInformationV2,
  237. TokenPrimary,
  238. ImpersonationLevel,
  239. Token
  240. );
  241. if ( !NT_SUCCESS(Status) ) {
  242. goto Cleanup;
  243. }
  244. } else {
  245. //
  246. // Impersonation token
  247. //
  248. Status = LsapCreateV2Token(
  249. LogonId,
  250. TokenSource,
  251. TokenInformationV2,
  252. TokenImpersonation,
  253. ImpersonationLevel,
  254. Token
  255. );
  256. if ( !NT_SUCCESS(Status) ) {
  257. goto Cleanup;
  258. }
  259. }
  260. //
  261. // Copy out the User Sid
  262. //
  263. Status = LsapDuplicateSid( &NewUserSid, TokenInformationV2->User.User.Sid );
  264. if ( !NT_SUCCESS( Status )) {
  265. goto Cleanup;
  266. }
  267. break;
  268. }
  269. //
  270. // Audit special privilege assignment, if there were any
  271. //
  272. if ( PrivilegesAssigned != NULL ) {
  273. //
  274. // Examine the list of privileges being assigned, and
  275. // audit special privileges as appropriate.
  276. //
  277. LsapAdtAuditSpecialPrivileges( PrivilegesAssigned, *LogonId, NewUserSid );
  278. }
  279. NewAccountName = &LocalAccountName ;
  280. NewAuthorityName = &LocalAuthorityName ;
  281. //
  282. // If the original was a null session, set the user name & domain name
  283. // to be anonymous.
  284. //
  285. if (OriginalTokenType == LsaTokenInformationNull)
  286. {
  287. NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength);
  288. if (NewAccountName->Buffer == NULL)
  289. {
  290. Status = STATUS_INSUFFICIENT_RESOURCES;
  291. goto Cleanup;
  292. }
  293. NewAccountName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength;
  294. RtlCopyUnicodeString(
  295. NewAccountName,
  296. &WellKnownSids[LsapAnonymousSidIndex].Name
  297. );
  298. NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength);
  299. if (NewAuthorityName->Buffer == NULL)
  300. {
  301. Status = STATUS_INSUFFICIENT_RESOURCES;
  302. goto Cleanup;
  303. }
  304. NewAuthorityName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength;
  305. RtlCopyUnicodeString(
  306. NewAuthorityName,
  307. &WellKnownSids[LsapAnonymousSidIndex].DomainName
  308. );
  309. }
  310. else
  311. {
  312. NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AccountName->MaximumLength);
  313. if (NewAccountName->Buffer == NULL)
  314. {
  315. Status = STATUS_INSUFFICIENT_RESOURCES;
  316. goto Cleanup;
  317. }
  318. NewAccountName->MaximumLength = AccountName->MaximumLength;
  319. RtlCopyUnicodeString(
  320. NewAccountName,
  321. AccountName
  322. );
  323. NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AuthorityName->MaximumLength);
  324. if (NewAuthorityName->Buffer == NULL)
  325. {
  326. Status = STATUS_INSUFFICIENT_RESOURCES;
  327. goto Cleanup;
  328. }
  329. NewAuthorityName->MaximumLength = AuthorityName->MaximumLength;
  330. RtlCopyUnicodeString(
  331. NewAuthorityName,
  332. AuthorityName
  333. );
  334. if (ARGUMENT_PRESENT(ProfilePath) ) {
  335. NewProfilePath = &LocalProfilePath ;
  336. NewProfilePath->Buffer = (LPWSTR) LsapAllocateLsaHeap(ProfilePath->MaximumLength);
  337. if (NewProfilePath->Buffer == NULL)
  338. {
  339. Status = STATUS_INSUFFICIENT_RESOURCES;
  340. goto Cleanup;
  341. }
  342. NewProfilePath->MaximumLength = ProfilePath->MaximumLength;
  343. RtlCopyUnicodeString(
  344. NewProfilePath,
  345. ProfilePath
  346. );
  347. }
  348. }
  349. Status = LsapSetLogonSessionAccountInfo(
  350. LogonId,
  351. NewAccountName,
  352. NewAuthorityName,
  353. NewProfilePath,
  354. &NewUserSid,
  355. LogonType,
  356. PrimaryCredential
  357. );
  358. if (!NT_SUCCESS(Status))
  359. {
  360. goto Cleanup;
  361. }
  362. LocalAccountName.Buffer = NULL ;
  363. LocalAuthorityName.Buffer = NULL ;
  364. LocalProfilePath.Buffer = NULL ;
  365. //
  366. // Set the token on the session
  367. //
  368. Status = LsapSetSessionToken( *Token, LogonId );
  369. if ( !NT_SUCCESS(Status) ) {
  370. goto Cleanup;
  371. }
  372. Cleanup:
  373. //
  374. // Clean up on failure
  375. //
  376. if ( !NT_SUCCESS(Status) ) {
  377. //
  378. // If we successfully built the token,
  379. // free it.
  380. //
  381. if ( *Token != NULL ) {
  382. NtClose( *Token );
  383. *Token = NULL;
  384. }
  385. }
  386. //
  387. // Always free the token information because the policy filter
  388. // changes it.
  389. //
  390. switch (TokenInformationType) {
  391. case LsaTokenInformationNull:
  392. LsapFreeTokenInformationNull( (PLSA_TOKEN_INFORMATION_NULL) TokenInformation );
  393. break;
  394. case LsaTokenInformationV1:
  395. LsapFreeTokenInformationV1( (PLSA_TOKEN_INFORMATION_V1) TokenInformation );
  396. break;
  397. case LsaTokenInformationV2:
  398. LsapFreeTokenInformationV2( (PLSA_TOKEN_INFORMATION_V2) TokenInformation );
  399. break;
  400. }
  401. if ( LocalAccountName.Buffer != NULL )
  402. {
  403. LsapFreeLsaHeap( LocalAccountName.Buffer );
  404. }
  405. if ( LocalAuthorityName.Buffer != NULL )
  406. {
  407. LsapFreeLsaHeap( LocalAuthorityName.Buffer );
  408. }
  409. if ( LocalProfilePath.Buffer != NULL )
  410. {
  411. LsapFreeLsaHeap( LocalProfilePath.Buffer );
  412. }
  413. if (NewUserSid != NULL) {
  414. LsapFreeLsaHeap( NewUserSid );
  415. }
  416. if ( PrivilegesAssigned != NULL ) {
  417. MIDL_user_free( PrivilegesAssigned );
  418. }
  419. return(Status);
  420. }