⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msvsam.c

📁 安全支持提供器接口(SSPI)源码
💻 C
📖 第 1 页 / 共 5 页
字号:

        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 + -