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

📄 nlmain.c

📁 安全支持提供器接口(SSPI)源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                //
                // Map the user's logon domain against the current mapping
                // in the registry.
                //

                Status = NlpMapLogonDomain(
                            &LogonDomainName,
                            &PrimaryCredential->LogonDomainName
                            );
                if (!NT_SUCCESS(Status)) {
                    goto Cleanup;
                }
#else
                LogonDomainName = PrimaryCredential->LogonDomainName;
#endif
            }

        } else if ( Status == STATUS_NO_SUCH_LOGON_SESSION ||
                    Status == STATUS_UNSUCCESSFUL ) {

            //
            // Clean up the status code
            //

            Status = STATUS_NO_SUCH_LOGON_SESSION;

            //
            // If the caller wants at least the password from the primary
            //  credential, just use a NULL session primary credential.
            //

            if ( (GetRespRequest->ParameterControl & USE_PRIMARY_PASSWORD ) ==
                    USE_PRIMARY_PASSWORD ) {

                PrimaryCredential = NULL;

            //
            // If part of the information was supplied by the caller,
            //  report the error to the caller.
            //
            } else {
                KdPrint(("MSV1_0: MspLm20GetChallengeResponse: cannot "
                         " GetPrimaryCredential %lx\n", Status ));
                goto Cleanup;
            }
        } else {
                KdPrint(("MSV1_0: MspLm20GetChallengeResponse: cannot "
                         " GetPrimaryCredential %lx\n", Status ));
                goto Cleanup;
        }

        Credential = PrimaryCredential;

    }


    //
    // If the caller passed in a password to use,
    //  use it to build a credential.
    //

    if ( (GetRespRequest->ParameterControl & USE_PRIMARY_PASSWORD) == 0 ) {

        NlpPutOwfsInPrimaryCredential( &GetRespRequest->Password,
                                       &BuiltCredential );

        //
        // Use the newly allocated credential to get the password information
        // from.
        //
        Credential = &BuiltCredential;

    }

    //
    // Build the appropriate response.
    //

    if ( Credential != NULL ) {

        //
        // If the DC is asserted to have been upgraded, we should use NTLM3
        //  if caller supplies the NTLM3 parameters
        //

        if ((NtLmProtocolSupported >= UseNtlm3) &&
            (GetRespRequest->ParameterControl & GCR_NTLM3_PARMS)
            ) {

            USHORT Ntlm3ResponseSize;
            UNICODE_STRING Ntlm3UserName;
            UNICODE_STRING Ntlm3LogonDomainName;
            UNICODE_STRING Ntlm3ServerName;

            // use the server name supplied by the caller
            Ntlm3ServerName = GetRespRequest->ServerName;

            // even if user name and domain are supplied, use current logged
            //  in user if so requested

            if (GetRespRequest->ParameterControl & USE_PRIMARY_PASSWORD) {
                Ntlm3UserName = Credential->UserName;
                Ntlm3LogonDomainName = Credential->LogonDomainName;
            } else {
                Ntlm3UserName = GetRespRequest->UserName;
                Ntlm3LogonDomainName = GetRespRequest->LogonDomainName;
            }

            //
            // Allocate the response
            //

            Ntlm3ResponseSize =
                sizeof(MSV1_0_NTLM3_RESPONSE) + Ntlm3ServerName.Length;

            pNtlm3Response = (*Lsa.AllocateLsaHeap)( Ntlm3ResponseSize );

            if ( pNtlm3Response == NULL ) {
                KdPrint(("MSV1_0: MspLm20GetChallengeResponse: No memory %ld\n",
                    Ntlm3ResponseSize ));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto Cleanup;
            }

            MsvpLm20GetNtlm3ChallengeResponse(
                &Credential->NtOwfPassword,
                &Ntlm3UserName,
                &Ntlm3LogonDomainName,
                &Ntlm3ServerName,
                GetRespRequest->ChallengeToClient,
                pNtlm3Response,  // BUGBUG??
                (PMSV1_0_LM3_RESPONSE)&LmResponse,
                &UserSessionKey,
                (PLM_SESSION_KEY)LanmanSessionKey
                );

            NtResponseString.Buffer = (PUCHAR) pNtlm3Response;
            NtResponseString.Length = Ntlm3ResponseSize;
            LmResponseString.Buffer = (PUCHAR) &LmResponse;
            LmResponseString.Length = sizeof(LmResponse);
        } else {

            //
            // if requested, generate our own challenge, and mix it with that
            //  of the server's
            //

            if (GetRespRequest->ParameterControl & GENERATE_CLIENT_CHALLENGE) {

                SspGenerateRandomBits(ChallengeFromClient, MSV1_0_CHALLENGE_LENGTH);

#ifdef USE_CONSTANT_CHALLENGE
                RtlZeroMemory(ChallengeFromClient, MSV1_0_CHALLENGE_LENGTH);
#endif

                RtlCopyMemory(
                    ChallengeToClient,
                    GetRespRequest->ChallengeToClient,
                    MSV1_0_CHALLENGE_LENGTH
                    );

                MsvpCalculateNtlm2Challenge (
                    GetRespRequest->ChallengeToClient,
                    ChallengeFromClient,
                    GetRespRequest->ChallengeToClient
                    );

            }

            Status = RtlCalculateNtResponse(
                        (PNT_CHALLENGE) GetRespRequest->ChallengeToClient,
                        &Credential->NtOwfPassword,
                        &NtResponse );

            if ( !NT_SUCCESS( Status ) ) {
                goto Cleanup;
            }


            //
            // send the client challenge back in the LM response slot if we made one
            //
            if (GetRespRequest->ParameterControl & GENERATE_CLIENT_CHALLENGE) {

                RtlZeroMemory(
                    &LmResponse,
                    sizeof(LmResponse)
                    );

                RtlCopyMemory(
                    &LmResponse,
                    ChallengeFromClient,
                    MSV1_0_CHALLENGE_LENGTH
                    );
            //
            // Return the LM response if policy set that way for backwards compatibility.
            //

            } else if ((NtLmProtocolSupported <= AllowLm) ) {
                Status = RtlCalculateLmResponse(
                            (PLM_CHALLENGE) GetRespRequest->ChallengeToClient,
                            &Credential->LmOwfPassword,
                            &LmResponse );

                if ( !NT_SUCCESS( Status ) ) {
                    goto Cleanup;
                }

            //
            //
            //  Can't return LM response -- so use NT response
            //   (to allow LM_KEY generatation)
            //

            } else {
                RtlCopyMemory(
                        &LmResponse,
                        &NtResponse,
                        sizeof(LmResponse)
                        );
            }

            NtResponseString.Buffer = (PUCHAR) &NtResponse;
            NtResponseString.Length = sizeof(NtResponse);
            LmResponseString.Buffer = (PUCHAR) &LmResponse;
            LmResponseString.Length = sizeof(LmResponse);

            //
            // Compute the session keys
            //

            if (GetRespRequest->ParameterControl & GENERATE_CLIENT_CHALLENGE) {

                //
                // assert: we're talking to an NT4-SP4 or later server
                //          and the user's DC hasn't been upgraded to NTLM++
                //  generate session key from MD4(NT hash) -
                //  aka NtUserSessionKey - that is different for each session
                //

                Status = RtlCalculateUserSessionKeyNt(
                                &NtResponse,
                                &Credential->NtOwfPassword,
                                &UserSessionKey );

                if ( !NT_SUCCESS( Status ) ) {
                    goto Cleanup;
                }

                MsvpCalculateNtlm2SessionKeys(
                    &UserSessionKey,
                    ChallengeToClient,
                    ChallengeFromClient,
                    (PUSER_SESSION_KEY)&UserSessionKey,
                    (PLM_SESSION_KEY)LanmanSessionKey
                    );

            } else if ( GetRespRequest->ParameterControl & RETURN_NON_NT_USER_SESSION_KEY){

                //
                // If the redir didn't negotiate an NT protocol with the server,
                //  use the lanman session key.
                //

                if ( Credential->LmPasswordPresent ) {

                    ASSERT( sizeof(UserSessionKey) >= sizeof(LanmanSessionKey) );

                    RtlCopyMemory( &UserSessionKey,
                                   &Credential->LmOwfPassword,
                                   sizeof(LanmanSessionKey) );
                }

            } else {

                if ( !Credential->NtPasswordPresent ) {

                    RtlCopyMemory( &Credential->NtOwfPassword,
                                &NlpNullNtOwfPassword,
                                sizeof(Credential->NtOwfPassword) );
                }

                Status = RtlCalculateUserSessionKeyNt(
                                &NtResponse,
                                &Credential->NtOwfPassword,
                                &UserSessionKey );

                if ( !NT_SUCCESS( Status ) ) {
                    goto Cleanup;
                }
            }

            if ( Credential->LmPasswordPresent ) {
                RtlCopyMemory( LanmanSessionKey,
                               &Credential->LmOwfPassword,
                               sizeof(LanmanSessionKey) );
            }

        } // UseNtlm3

    }


    //
    // Allocate a buffer to return to the caller.
    //

    *ReturnBufferSize = sizeof(MSV1_0_GETCHALLENRESP_RESPONSE) +
                        LogonDomainName.Length + sizeof(WCHAR) +
                        UserName.Length + sizeof(WCHAR) +
                        NtResponseString.Length + sizeof(WCHAR) +
                        LmResponseString.Length + sizeof(WCHAR);

    Status = NlpAllocateClientBuffer( &ClientBufferDesc,
                                      sizeof(MSV1_0_GETCHALLENRESP_RESPONSE),
                                      *ReturnBufferSize );


    if ( !NT_SUCCESS( Status ) ) {
        goto Cleanup;
    }

    GetRespResponse = (PMSV1_0_GETCHALLENRESP_RESPONSE) ClientBufferDesc.MsvBuffer;


    //
    // Fill in the return buffer.
    //

    GetRespResponse->MessageType = MsV1_0Lm20GetChallengeResponse;
    RtlCopyMemory( GetRespResponse->UserSessionKey,
                   &UserSessionKey,
                   sizeof(UserSessionKey));
    RtlCopyMemory( GetRespResponse->LanmanSessionKey,
                   LanmanSessionKey,
                   sizeof(LanmanSessionKey) );


    //
    // Copy the logon domain name (the string may be empty)
    //

    NlpPutClientString( &ClientBufferDesc,
                        &GetRespResponse->LogonDomainName,
                        &LogonDomainName );

    //
    // Copy the user name (the string may be empty)
    //

    NlpPutClientString( &ClientBufferDesc,
                        &GetRespResponse->UserName,
                        &UserName );

    //
    // Copy the Challenge Responses to the client buffer.
    //

    NlpPutClientString(
                &ClientBufferDesc,
                (PUNICODE_STRING)
                    &GetRespResponse->CaseSensitiveChallengeResponse,
                (PUNICODE_STRING) &NtResponseString );

    NlpPutClientString(
                &ClientBufferDesc,
                (PUNICODE_STRING)
                    &GetRespResponse->CaseInsensitiveChallengeResponse,
                (PUNICODE_STRING)&LmResponseString );


    //
    // Flush the buffer to the client's address space.
    //

    Status = NlpFlushClientBuffer( &ClientBufferDesc,
                                   ProtocolReturnBuffer );

Cleanup:

    //
    // If we weren't successful, free the buffer in the clients address space.
    //

    if ( !NT_SUCCESS(Status) ) {
        NlpFreeClientBuffer( &ClientBufferDesc );
    }

    //
    // Cleanup locally used resources
    //

    if ( PrimaryCredential != NULL ) {
        (*Lsa.FreeLsaHeap)( PrimaryCredential );
    }

#ifndef DONT_MAP_DOMAIN_ON_REQUEST

    if (LogonDomainName.Buffer != NULL) {
        NtLmFree(LogonDomainName.Buffer);
    }
#endif

    if ( pNtlm3Response != NULL ) {
        (*Lsa.FreeLsaHeap)( pNtlm3Response );
    }

    //
    // Return status to the caller.
    //

    *ProtocolStatus = Status;
    return STATUS_SUCCESS;

}


NTSTATUS
MspLm20EnumUsers (
    IN PLSA_CLIENT_REQUEST ClientRequest,
    IN PVOID ProtocolSubmitBuffer,
    IN PVOID ClientBufferBase,
    IN ULONG SubmitBufferSize,
    OUT PVOID *ProtocolReturnBuffer,
    OUT PULONG ReturnBufferSize,
    OUT PNTSTATUS ProtocolStatus
    )

/*++

Routine Description:

    This routine is the dispatch routine for LsaCallAuthenticationPackage()
    with a message type of MsV1_0Lm20EnumerateUsers.  This routine
    enumerates all of the interactive, service, and batch logons to the MSV1_0
    authentication package.

Arguments:

    The arguments to this routine are identical to those of LsaApCallPackage.
    Only the special attributes of these parameters as they apply to
    this routine are mentioned here.

Return Value:

    STATUS_SUCCESS - Indicates the service completed successfully.



--*/

{
    NTSTATUS Status;
    PMSV1_0_ENUMUSERS_REQUEST EnumRequest;
    PMSV1_0_ENUMUSERS_RESPONSE EnumResponse;
    CLIENT_BUFFER_DESC ClientBufferDesc;
    ULONG LogonCount = 0;
    PACTIVE_LOGON Logon;
    BOOLEAN ActiveLogonsAreLocked = FALSE;

    PUCHAR Where;

    //
    // Ensure the specified Submit Buffer is of reasonable size and
    // relocate all of the pointers to be relative to the LSA allocated
    // buffer.
    //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -