|
|
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1994
//
// File: policy.cxx
//
// Contents: SpmBuildCairoToken
//
//
// History: 23-May-1994 MikeSw Created
//
//------------------------------------------------------------------------
#include <lsapch.hxx>
extern "C" { #include "adtp.h"
}
//+-------------------------------------------------------------------------
//
// Function: LsapCreateToken
//
// Synopsis: Builds a token from the various pieces of information
// generated during a logon.
//
// Effects:
//
// Arguments: pUserSid - sid of user to create token for
// pTokenGroups - groups passed in to LogonUser or from PAC to
// be put in token
// pTokenPrivs - privileges from PAC to put in token
// TokenType - type of token to create
// pTokenSource - source of the token
// pLogonId - Gets logon ID
// phToken - Get handle to token
//
// Requires:
//
// Returns:
//
// Notes: TokenInformation is always freed, even on failure.
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI LsapCreateToken( IN PLUID LogonId, IN PTOKEN_SOURCE TokenSource, IN SECURITY_LOGON_TYPE LogonType, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, IN LSA_TOKEN_INFORMATION_TYPE InputTokenInformationType, IN PVOID InputTokenInformation, IN PTOKEN_GROUPS LocalGroups, IN PUNICODE_STRING AccountName, IN PUNICODE_STRING AuthorityName, IN PUNICODE_STRING WorkstationName, IN OPTIONAL PUNICODE_STRING ProfilePath, OUT PHANDLE Token, OUT PNTSTATUS SubStatus ) { SECPKG_PRIMARY_CRED PrimaryCredential;
ZeroMemory( &PrimaryCredential, sizeof(PrimaryCredential) );
if( AccountName != NULL ) { PrimaryCredential.DownlevelName = *AccountName; }
if( AuthorityName != NULL ) { PrimaryCredential.DomainName = *AuthorityName; }
return LsapCreateTokenEx( LogonId, TokenSource, LogonType, ImpersonationLevel, InputTokenInformationType, InputTokenInformation, LocalGroups, WorkstationName, ProfilePath, &PrimaryCredential, SecSessionPrimaryCred, Token, SubStatus );
}
//+-------------------------------------------------------------------------
//
// Function: LsapCreateTokenEx
//
// Synopsis: Builds a token from the various pieces of information
// generated during a logon.
//
// Effects:
//
// Arguments: pUserSid - sid of user to create token for
// pTokenGroups - groups passed in to LogonUser or from PAC to
// be put in token
// pTokenPrivs - privileges from PAC to put in token
// TokenType - type of token to create
// pTokenSource - source of the token
// pLogonId - Gets logon ID
// phToken - Get handle to token
//
// Requires:
//
// Returns:
//
// Notes: TokenInformation is always freed, even on failure.
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI LsapCreateTokenEx( IN PLUID LogonId, IN PTOKEN_SOURCE TokenSource, IN SECURITY_LOGON_TYPE LogonType, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, IN LSA_TOKEN_INFORMATION_TYPE InputTokenInformationType, IN PVOID InputTokenInformation, IN PTOKEN_GROUPS LocalGroups, IN PUNICODE_STRING WorkstationName, IN PUNICODE_STRING ProfilePath, IN PVOID SessionInformation, IN SECPKG_SESSIONINFO_TYPE SessionInformationType, OUT PHANDLE Token, OUT PNTSTATUS SubStatus ) { NTSTATUS Status; PPRIVILEGE_SET PrivilegesAssigned = NULL; PLSA_TOKEN_INFORMATION_V2 TokenInformationV2 = NULL; PLSA_TOKEN_INFORMATION_NULL TokenInformationNull = NULL; LSA_TOKEN_INFORMATION_TYPE OriginalTokenType = InputTokenInformationType; QUOTA_LIMITS QuotaLimits; PUNICODE_STRING NewAccountName = NULL; PUNICODE_STRING NewAuthorityName = NULL; PUNICODE_STRING NewProfilePath = NULL; UNICODE_STRING LocalAccountName = { 0 }; UNICODE_STRING LocalAuthorityName = { 0 }; UNICODE_STRING LocalProfilePath = { 0 }; PSID NewUserSid = NULL; LSA_TOKEN_INFORMATION_TYPE TokenInformationType = InputTokenInformationType; PVOID TokenInformation = InputTokenInformation;
PSECPKG_PRIMARY_CRED PrimaryCredential; PUNICODE_STRING AccountName; PUNICODE_STRING AuthorityName;
*Token = NULL; *SubStatus = STATUS_SUCCESS;
if( SessionInformationType != SecSessionPrimaryCred ) { return STATUS_INVALID_PARAMETER; }
PrimaryCredential = (PSECPKG_PRIMARY_CRED)SessionInformation;
AccountName = &PrimaryCredential->DownlevelName; AuthorityName = &PrimaryCredential->DomainName;
//
// Pass the token information through the Local Security Policy
// Filter/Augmentor. This may cause some or all of the token
// information to be replaced/augmented.
//
Status = LsapAuUserLogonPolicyFilter( LogonType, &TokenInformationType, &TokenInformation, LocalGroups, &QuotaLimits, &PrivilegesAssigned );
if ( !NT_SUCCESS(Status) ) {
goto Cleanup; }
//
// Check if we only allow admins to logon. We do allow null session
// connections since they are severly restricted, though. Since the
// token type may have been changed, we use the token type originally
// returned by the package.
//
if (LsapAllowAdminLogonsOnly && ((OriginalTokenType == LsaTokenInformationV1) || (OriginalTokenType == LsaTokenInformationV2))&& !LsapSidPresentInGroups( ((PLSA_TOKEN_INFORMATION_V2) TokenInformation)->Groups, (SID *)LsapAliasAdminsSid)) {
//
// Set the status to be invalid workstation, since all accounts
// except administrative ones are locked out for this
// workstation.
//
*SubStatus = STATUS_INVALID_WORKSTATION; Status = STATUS_ACCOUNT_RESTRICTION; goto Cleanup; }
//
// Case on the token information returned (and subsequently massaged)
// to create the correct kind of token.
//
switch (TokenInformationType) {
case LsaTokenInformationNull:
TokenInformationNull = (PLSA_TOKEN_INFORMATION_NULL) TokenInformation;
//
// The user hasn't logged on to any particular account.
// An impersonation token with WORLD as owner
// will be created.
//
Status = LsapCreateNullToken( LogonId, TokenSource, TokenInformationNull, Token );
if ( !NT_SUCCESS(Status) ) { goto Cleanup; }
break;
case LsaTokenInformationV1: case LsaTokenInformationV2:
TokenInformationV2 = (PLSA_TOKEN_INFORMATION_V2) TokenInformation;
//
// the type of token created depends upon the type of logon
// being requested:
//
// InteractiveLogon => PrimaryToken
// BatchLogon => PrimaryToken
// NetworkLogon => ImpersonationToken
//
if (LogonType != Network) {
//
// Primary token
//
Status = LsapCreateV2Token( LogonId, TokenSource, TokenInformationV2, TokenPrimary, ImpersonationLevel, Token );
if ( !NT_SUCCESS(Status) ) { goto Cleanup; }
} else {
//
// Impersonation token
//
Status = LsapCreateV2Token( LogonId, TokenSource, TokenInformationV2, TokenImpersonation, ImpersonationLevel, Token );
if ( !NT_SUCCESS(Status) ) { goto Cleanup; }
}
//
// Copy out the User Sid
//
Status = LsapDuplicateSid( &NewUserSid, TokenInformationV2->User.User.Sid );
if ( !NT_SUCCESS( Status )) { goto Cleanup; }
break;
}
//
// Audit special privilege assignment, if there were any
//
if ( PrivilegesAssigned != NULL ) {
//
// Examine the list of privileges being assigned, and
// audit special privileges as appropriate.
//
LsapAdtAuditSpecialPrivileges( PrivilegesAssigned, *LogonId, NewUserSid );
}
NewAccountName = &LocalAccountName ; NewAuthorityName = &LocalAuthorityName ;
//
// If the original was a null session, set the user name & domain name
// to be anonymous.
//
if (OriginalTokenType == LsaTokenInformationNull) { NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength); if (NewAccountName->Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } NewAccountName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].Name.MaximumLength; RtlCopyUnicodeString( NewAccountName, &WellKnownSids[LsapAnonymousSidIndex].Name );
NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength); if (NewAuthorityName->Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } NewAuthorityName->MaximumLength = WellKnownSids[LsapAnonymousSidIndex].DomainName.MaximumLength; RtlCopyUnicodeString( NewAuthorityName, &WellKnownSids[LsapAnonymousSidIndex].DomainName );
} else { NewAccountName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AccountName->MaximumLength); if (NewAccountName->Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } NewAccountName->MaximumLength = AccountName->MaximumLength; RtlCopyUnicodeString( NewAccountName, AccountName );
NewAuthorityName->Buffer = (LPWSTR) LsapAllocateLsaHeap(AuthorityName->MaximumLength); if (NewAuthorityName->Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } NewAuthorityName->MaximumLength = AuthorityName->MaximumLength; RtlCopyUnicodeString( NewAuthorityName, AuthorityName );
if (ARGUMENT_PRESENT(ProfilePath) ) { NewProfilePath = &LocalProfilePath ;
NewProfilePath->Buffer = (LPWSTR) LsapAllocateLsaHeap(ProfilePath->MaximumLength); if (NewProfilePath->Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } NewProfilePath->MaximumLength = ProfilePath->MaximumLength; RtlCopyUnicodeString( NewProfilePath, ProfilePath );
} }
Status = LsapSetLogonSessionAccountInfo( LogonId, NewAccountName, NewAuthorityName, NewProfilePath, &NewUserSid, LogonType, PrimaryCredential );
if (!NT_SUCCESS(Status)) { goto Cleanup; }
LocalAccountName.Buffer = NULL ; LocalAuthorityName.Buffer = NULL ; LocalProfilePath.Buffer = NULL ;
//
// Set the token on the session
//
Status = LsapSetSessionToken( *Token, LogonId );
if ( !NT_SUCCESS(Status) ) { goto Cleanup; }
Cleanup:
//
// Clean up on failure
//
if ( !NT_SUCCESS(Status) ) {
//
// If we successfully built the token,
// free it.
//
if ( *Token != NULL ) { NtClose( *Token ); *Token = NULL; } }
//
// Always free the token information because the policy filter
// changes it.
//
switch (TokenInformationType) {
case LsaTokenInformationNull:
LsapFreeTokenInformationNull( (PLSA_TOKEN_INFORMATION_NULL) TokenInformation ); break;
case LsaTokenInformationV1:
LsapFreeTokenInformationV1( (PLSA_TOKEN_INFORMATION_V1) TokenInformation ); break;
case LsaTokenInformationV2:
LsapFreeTokenInformationV2( (PLSA_TOKEN_INFORMATION_V2) TokenInformation ); break;
}
if ( LocalAccountName.Buffer != NULL ) { LsapFreeLsaHeap( LocalAccountName.Buffer ); }
if ( LocalAuthorityName.Buffer != NULL ) { LsapFreeLsaHeap( LocalAuthorityName.Buffer ); }
if ( LocalProfilePath.Buffer != NULL ) { LsapFreeLsaHeap( LocalProfilePath.Buffer ); }
if (NewUserSid != NULL) { LsapFreeLsaHeap( NewUserSid ); } if ( PrivilegesAssigned != NULL ) {
MIDL_user_free( PrivilegesAssigned ); } return(Status); }
|