📄 msvsam.c
字号:
if ((CompleteMembership->SidAndAttributes[Index].Attributes & MSVP_LOCAL_GROUP_ATTR) != 0) {
LocalMembership->Groups[LocalCount].Attributes = CompleteMembership->SidAndAttributes[Index].Attributes & ~MSVP_LOCAL_GROUP_ATTR;
LocalMembership->Groups[LocalCount].RelativeId =
*RtlSubAuthoritySid(
CompleteMembership->SidAndAttributes[Index].Sid,
*RtlSubAuthorityCountSid(
CompleteMembership->SidAndAttributes[Index].Sid
) - 1
);
LocalCount++;
} else {
GlobalMembership->SidAndAttributes[GlobalCount] = CompleteMembership->SidAndAttributes[Index];
GlobalCount++;
}
}
*GlobalMembershipSize = GlobalSize;
Cleanup:
if (!NT_SUCCESS(Status)) {
if (LocalMembership->Groups != NULL)
{
MIDL_user_free(LocalMembership->Groups);
LocalMembership->Groups = NULL;
}
if (GlobalMembership->SidAndAttributes != NULL)
{
MIDL_user_free(GlobalMembership->SidAndAttributes);
GlobalMembership->SidAndAttributes = NULL;
}
}
return(Status);
}
NTSTATUS
MsvpSamValidate (
IN SAMPR_HANDLE DomainHandle,
IN BOOLEAN UasCompatibilityRequired,
IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType,
IN PUNICODE_STRING LogonServer,
IN PUNICODE_STRING LogonDomainName,
IN PSID LogonDomainId,
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
IN PVOID LogonInformation,
IN ULONG GuestRelativeId,
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
OUT PVOID * ValidationInformation,
OUT PBOOLEAN Authoritative,
OUT PBOOLEAN BadPasswordCountZeroed
)
/*++
Routine Description:
Process an interactive, network, or session logon. It calls
SamIUserValidation, validates the passed in credentials, updates the logon
statistics and packages the result for return to the caller.
This routine is called by MsvSamValidate.
Arguments:
DomainHandle -- Specifies a handle to the SamDomain to use to
validate the request.
UasCompatibilityRequired -- TRUE iff UasCompatibilityMode is on.
SecureChannelType -- The secure channel type this request was made on.
LogonServer -- Specifies the server name of the caller.
LogonDomainName -- Specifies the domain of the caller.
LogonDomainId -- Specifies the DomainId of the domain of the caller.
LogonLevel -- Specifies the level of information given in
LogonInformation.
LogonInformation -- Specifies the description for the user
logging on. The LogonDomainName field should be ignored.
The caller is responsible for validating this field.
GuestRelativeId - If non-zero, specifies the relative ID of the account
to validate against.
ValidationLevel -- Specifies the level of information returned in
ValidationInformation. Must be NetlogonValidationSamInfo or
NetlogonValidationSamInfo2.
ValidationInformation -- Returns the requested validation
information. This buffer must be freed user MIDL_user_free.
This information is only return on STATUS_SUCCESS.
Authoritative -- Returns whether the status returned is an
authoritative status which should be returned to the original
caller. If not, this logon request may be tried again on another
domain controller. This parameter is returned regardless of the
status code.
BadPasswordCountZeroed - Returns TRUE iff we zeroed the BadPasswordCount
field of this user.
Return Value:
STATUS_SUCCESS: if there was no error.
STATUS_INVALID_INFO_CLASS: LogonLevel or ValidationLevel are invalid.
STATUS_NO_SUCH_USER: The specified user has no account.
STATUS_WRONG_PASSWORD: The password was invalid.
Other return codes from SamIUserValidation
--*/
{
NTSTATUS Status;
NTSTATUS SubAuthExStatus = STATUS_SUCCESS;
PNETLOGON_LOGON_IDENTITY_INFO LogonInfo;
SAMPR_HANDLE UserHandle = NULL;
ULONG RelativeId = GuestRelativeId;
ULONG SamFlags;
PSID LocalSidUser = NULL;
PSAMPR_USER_INFO_BUFFER UserAllInfo = NULL;
PSAMPR_USER_ALL_INFORMATION UserAll = NULL;
SAMPR_GET_GROUPS_BUFFER GroupsBuffer;
ULONG UserFlags = 0;
USER_SESSION_KEY UserSessionKey;
LM_SESSION_KEY LmSessionKey;
ULONG WhichFields = 0;
UNICODE_STRING LocalUserName;
UNICODE_STRING LocalWorkstation;
ULONG UserAccountControl;
LARGE_INTEGER LogonTime;
LARGE_INTEGER LogoffTime;
LARGE_INTEGER KickoffTime;
LARGE_INTEGER AccountExpires;
LARGE_INTEGER PasswordMustChange;
LARGE_INTEGER PasswordLastSet;
PNETLOGON_VALIDATION_SAM_INFO2 ValidationSam = NULL;
ULONG ValidationSamSize;
PUCHAR Where;
ULONG Index;
SAMPR_RETURNED_USTRING_ARRAY NameArray;
SAMPR_ULONG_ARRAY UseArray;
SID_AND_ATTRIBUTES_LIST GroupMembership;
SID_AND_ATTRIBUTES_LIST GlobalGroupMembership;
ULONG GlobalMembershipSize = 0;
MSV1_0_VALIDATION_INFO SubAuthValidationInformation;
BOOLEAN fSubAuthEx = FALSE;
BOOLEAN fMachineAccount;
ULONG ActionsPerformed = 0;
LogonInfo = (PNETLOGON_LOGON_IDENTITY_INFO) LogonInformation;
//
// check if caller requested that logon only target specified domain.
//
if( LogonInfo->ParameterControl & MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY &&
LogonInfo->LogonDomainName.Length ) {
//
// common case is a match for LogonDomainName, so avoid taking locks
// until mis-match occurs.
//
if(!RtlEqualDomainName( &LogonInfo->LogonDomainName, LogonDomainName )) {
WCHAR LocalTarget[ DNS_MAX_NAME_LENGTH + 1 ];
WCHAR SpecifiedTarget[ DNS_MAX_NAME_LENGTH + 1 ];
ULONG cchLocalTarget = 0;
ULONG cchSpecifiedTarget = 0;
//
// pickup the local target name, based on whether this computer is
// a domain controller.
//
EnterCriticalSection(&NtLmGlobalCritSect);
if( NlpWorkstation ) {
if( (NtLmGlobalUnicodeDnsComputerNameString.Length + sizeof(WCHAR)) <=
sizeof( LocalTarget ) ) {
RtlCopyMemory(
LocalTarget,
NtLmGlobalUnicodeDnsComputerName,
NtLmGlobalUnicodeDnsComputerNameString.Length
);
cchLocalTarget = (NtLmGlobalUnicodeDnsComputerNameString.Length) /
sizeof(WCHAR);
}
} else {
if( (NtLmGlobalUnicodeDnsDomainNameString.Length + sizeof(WCHAR)) <=
sizeof( LocalTarget ) ) {
RtlCopyMemory(
LocalTarget,
NtLmGlobalUnicodeDnsDomainName,
NtLmGlobalUnicodeDnsDomainNameString.Length
);
cchLocalTarget = (NtLmGlobalUnicodeDnsDomainNameString.Length) /
sizeof(WCHAR);
}
}
LeaveCriticalSection(&NtLmGlobalCritSect);
//
// pull out target name.
//
if( (LogonInfo->LogonDomainName.Length + sizeof(WCHAR)) <= sizeof( SpecifiedTarget ) ) {
cchSpecifiedTarget = (LogonInfo->LogonDomainName.Length) / sizeof(WCHAR);
RtlCopyMemory(
SpecifiedTarget,
LogonInfo->LogonDomainName.Buffer,
LogonInfo->LogonDomainName.Length
);
}
if ( cchLocalTarget && cchSpecifiedTarget ) {
LocalTarget[ cchLocalTarget ] = L'\0';
SpecifiedTarget[ cchSpecifiedTarget ] = L'\0';
if(!DnsNameCompare_W( LocalTarget, SpecifiedTarget ) ) {
*Authoritative = FALSE;
return STATUS_NO_SUCH_USER;
}
}
}
}
//
// Initialization.
//
RtlZeroMemory(
&SubAuthValidationInformation,
sizeof(MSV1_0_VALIDATION_INFO));
SubAuthValidationInformation.Authoritative = TRUE;
SubAuthValidationInformation.WhichFields = 0;
NameArray.Count = 0;
NameArray.Element = NULL;
UseArray.Count = 0;
UseArray.Element = NULL;
*BadPasswordCountZeroed = FALSE;
GroupMembership.Count = 0;
GroupMembership.SidAndAttributes = NULL;
GlobalGroupMembership.Count = 0;
GlobalGroupMembership.SidAndAttributes = NULL;
GroupsBuffer.MembershipCount = 0;
GroupsBuffer.Groups = NULL;
(VOID) NtQuerySystemTime( &LogonTime );
//
// Determine what account types are valid.
//
// Normal user accounts are always allowed.
//
UserAccountControl = USER_NORMAL_ACCOUNT;
*Authoritative = TRUE;
switch ( LogonLevel ) {
case NetlogonInteractiveInformation:
case NetlogonServiceInformation:
break;
case NetlogonNetworkInformation:
//
// Local user (Temp Duplicate) accounts are only used on the machine
// being directly logged onto.
// (Nor are interactive or service logons allowed to them.)
//
if ( SecureChannelType == MsvApSecureChannel ) {
UserAccountControl |= USER_TEMP_DUPLICATE_ACCOUNT;
}
//
// Machine accounts can be accessed on network connections.
//
UserAccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT |
USER_WORKSTATION_TRUST_ACCOUNT |
USER_SERVER_TRUST_ACCOUNT;
break;
default:
*Authoritative = TRUE;
return STATUS_INVALID_INFO_CLASS;
}
//
// Check the ValidationLevel
//
switch (ValidationLevel) {
case NetlogonValidationSamInfo:
case NetlogonValidationSamInfo2:
break;
default:
*Authoritative = TRUE;
return STATUS_INVALID_INFO_CLASS;
}
//
// Convert the user name to a RelativeId.
//
if ( RelativeId != 0 ) {
UCHAR cDomainSubAuthorities;
UCHAR SubAuthIndex;
ULONG cbLocalSidUser;
PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority;
//
// build a Sid out of the DomainId and the supplied Rid.
//
cDomainSubAuthorities = *RtlSubAuthorityCountSid( LogonDomainId );
pIdentifierAuthority = RtlIdentifierAuthoritySid( LogonDomainId );
cbLocalSidUser = RtlLengthRequiredSid( (ULONG)(cDomainSubAuthorities + 1) );
LocalSidUser = MIDL_user_allocate( cbLocalSidUser );
if (LocalSidUser == NULL) {
*Authoritative = FALSE;
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
Status = RtlInitializeSid(LocalSidUser, pIdentifierAuthority, (UCHAR)((DWORD)cDomainSubAuthorities+1));
if(!NT_SUCCESS(Status)) {
*Authoritative = FALSE;
goto Cleanup;
}
//
// loop copying subauthorities.
//
for( SubAuthIndex = 0 ; SubAuthIndex < cDomainSubAuthorities ; SubAuthIndex++ )
{
*RtlSubAuthoritySid( LocalSidUser, (ULONG)SubAuthIndex ) =
*RtlSubAuthoritySid( LogonDomainId, (ULONG)SubAuthIndex );
}
//
// append relative ID.
//
*RtlSubAuthoritySid(LocalSidUser, cDomainSubAuthorities) = RelativeId;
LocalUserName.Buffer = LocalSidUser;
LocalUserName.Length = (USHORT)cbLocalSidUser;
LocalUserName.MaximumLength = (USHORT)cbLocalSidUser;
SamFlags = SAM_OPEN_BY_SID;
} else {
LocalUserName = LogonInfo->UserName;
SamFlags = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -