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

📄 msvpaswd.c

📁 安全支持提供器接口(SSPI)源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        // Open the LSA if we haven't already.
        //

        if (LSAPolicyHandle == NULL) {

            InitializeObjectAttributes( &LSAObjectAttributes,
                                        NULL,             // Name
                                        0,                // Attributes
                                        NULL,             // Root
                                        NULL );           // Security Descriptor

            TempStatus = LsaOpenPolicy( UncComputerName,
                                        &LSAObjectAttributes,
                                        POLICY_VIEW_LOCAL_INFORMATION,
                                        &LSAPolicyHandle );

            if( !NT_SUCCESS(TempStatus) ) {
                KdPrint(("MspChangePasswordSam: LsaOpenPolicy(%wZ) failed, status %x\n",
                     UncComputerName, TempStatus));
                LSAPolicyHandle = NULL;
            }


        }

        if (LSAPolicyHandle != NULL) {
            TempStatus = LsaQueryInformationPolicy(
                            LSAPolicyHandle,
                            PolicyPrimaryDomainInformation,
                            (PVOID *) PrimaryDomainInfo );

            if( !NT_SUCCESS(TempStatus) ) {
                KdPrint(("MspChangePasswordSam: LsaQueryInformationPolicy(%wZ) failed, status %x\n",
                         UncComputerName, TempStatus));
                *PrimaryDomainInfo = NULL;
    #ifdef COMPILED_BY_DEVELOPER
            } else {
                KdPrint(("MspChangePasswordSam: %wZ is really a BDC in domain %wZ\n",
                         UncComputerName, &(*PrimaryDomainInfo)->Name));
    #endif // COMPILED_BY_DEVELOPER
            }
        }

        Status = STATUS_BACKUP_CONTROLLER;

    }

    //
    // Check for non-authoritative failures
    //

    if (( Status != STATUS_ACCESS_DENIED) &&
        ( Status != STATUS_WRONG_PASSWORD ) &&
        ( Status != STATUS_NO_SUCH_USER ) &&
        ( Status != STATUS_PASSWORD_RESTRICTION ) &&
        ( Status != STATUS_ACCOUNT_RESTRICTION ) &&
        ( Status != STATUS_INVALID_DOMAIN_ROLE) ) {
        *Authoritative = FALSE;
    }

    //
    // Stop impersonating.
    //

    {
        NTSTATUS TempStatus;

        TempStatus = MspStopImpersonating();

    }

    //
    // Free Locally used resources
    //


    if (SamHandle) {
        SamCloseHandle(SamHandle);
    }

    if (DomainHandle) {
        SamCloseHandle(DomainHandle);
    }

    if( LSAPolicyHandle != NULL ) {
        LsaClose( LSAPolicyHandle );
    }

    if ( AccountDomainInfo != NULL ) {
        (VOID) LsaFreeMemory( AccountDomainInfo );
    }

    return Status;
}


NTSTATUS
MspChangePasswordDownlevel(
    IN PUNICODE_STRING UncComputerName,
    IN PUNICODE_STRING UserNameU,
    IN PUNICODE_STRING OldPasswordU,
    IN PUNICODE_STRING NewPasswordU,
    OUT PBOOLEAN Authoritative
    )

/*++

Routine Description:

    This routine is called by MspChangePassword to change the password
    on an OS/2 User-level server.  First we try sending an encrypted
    request to the server, failing that we fall back on plaintext.

Arguments:

    UncComputerName - Pointer to Unicode String containing the Name of the
        target machine.  This name must begin with two backslashes and
        must be null terminated.

    UserNameU    - Name of the user to change password for.

    OldPasswordU - Plaintext current password.

    NewPasswordU - Plaintext replacement password.

    Authoritative - If the attempt failed with an error that would
        otherwise cause the password attempt to fail, this flag, if false,
        indicates that the error was not authoritative and the attempt
        should proceed.

Return Value:

    STATUS_SUCCESS - Indicates the service completed successfully.

--*/

{
    NTSTATUS         Status;
    NET_API_STATUS   NetStatus;
    DWORD            Length;
    LPWSTR           UserName = NULL;
    LPWSTR           OldPassword = NULL;
    LPWSTR           NewPassword = NULL;

    *Authoritative = TRUE;

    //
    // Convert UserName from UNICODE_STRING to null-terminated wide string
    // for use by RxNetUserPasswordSet.
    //

    Length = UserNameU->Length;

    UserName = RtlAllocateHeap(
                   MspHeap, 0,
                   Length + sizeof(TCHAR)
                   );

    if ( NULL == UserName ) {

        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    RtlCopyMemory( UserName, UserNameU->Buffer, Length );

    UserName[ Length / sizeof(TCHAR) ] = 0;

    //
    // Convert OldPassword from UNICODE_STRING to null-terminated wide string.
    //

    Length = OldPasswordU->Length;

    OldPassword = RtlAllocateHeap( MspHeap, 0, Length + sizeof(TCHAR) );

    if ( NULL == OldPassword ) {

        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    RtlCopyMemory( OldPassword, OldPasswordU->Buffer, Length );

    OldPassword[ Length / sizeof(TCHAR) ] = 0;

    //
    // Convert NewPassword from UNICODE_STRING to null-terminated wide string.
    //

    Length = NewPasswordU->Length;

    NewPassword = RtlAllocateHeap( MspHeap, 0, Length + sizeof(TCHAR) );

    if ( NULL == NewPassword ) {

        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    RtlCopyMemory( NewPassword, NewPasswordU->Buffer, Length );

    NewPassword[ Length / sizeof(TCHAR) ] = 0;

#ifdef COMPILED_BY_DEVELOPER

    KdPrint(("MSV1_0: Changing password on downlevel server:\n"
        "\tUncComputerName: %wZ\n"
        "\tUserName:     %ws\n"
        "\tOldPassword:  %ws\n"
        "\tNewPassword:  %ws\n",
        UncComputerName,
        UserName,
        OldPassword,
        NewPassword
        ));

#endif // COMPILED_BY_DEVELOPER

    //
    // Attempt to change password on downlevel server.
    //

    NetStatus = RxNetUserPasswordSet(
                    UncComputerName->Buffer,
                    UserName,
                    OldPassword,
                    NewPassword);

    MsvPaswdLogPrint(("RxNetUserPasswordSet on machine %ws for user %ws returned 0x%x\n",
        UncComputerName->Buffer,
        UserName,
        NetStatus
        ));

#ifdef COMPILED_BY_DEVELOPER
    KdPrint(("MSV1_0: RxNUserPasswordSet returns %d.\n", NetStatus));
#endif // COMPILED_BY_DEVELOPER

    // Since we overload the computername as the domain name,
    // map NERR_InvalidComputer to STATUS_NO_SUCH_DOMAIN, since
    // that will give the user a nice error message.
    //
    // ERROR_PATH_NOT_FOUND is returned on a standalone workstation that
    //  doesn't have the network installed.
    //

    if (NetStatus == NERR_InvalidComputer ||
        NetStatus == ERROR_PATH_NOT_FOUND) {

        Status = STATUS_NO_SUCH_DOMAIN;

    // ERROR_SEM_TIMEOUT can be returned when the computer name doesn't
    //  exist.
    //
    // ERROR_REM_NOT_LIST can also be returned when the computer name
    //  doesn't exist.
    //

    } else if ( NetStatus == ERROR_SEM_TIMEOUT ||
                NetStatus == ERROR_REM_NOT_LIST) {

        Status = STATUS_BAD_NETWORK_PATH;

    } else if ( (NetStatus == ERROR_INVALID_PARAMETER) &&
                ((wcslen(NewPassword) > LM20_PWLEN) ||
                 (wcslen(OldPassword) > LM20_PWLEN)) ) {

        //
        // The net api returns ERROR_INVALID_PARAMETER if the password
        // could not be converted to the LM OWF password.  Return
        // STATUS_PASSWORD_RESTRICTION for this.
        //

        Status = STATUS_PASSWORD_RESTRICTION;

        //
        // We never made it to the other machine, so we should continue
        // trying to change the password.
        //

        *Authoritative = FALSE;
    } else {
        Status = NetpApiStatusToNtStatus( NetStatus );
    }

Cleanup:

    //
    // Free UserName if used.
    //

    if (UserName) {

        RtlFreeHeap(MspHeap, 0, UserName);
    }

    //
    // Free OldPassword if used. (Don't let password make it to page file)
    //

    if (OldPassword) {
        RtlZeroMemory( OldPassword, wcslen(OldPassword)*sizeof(WCHAR) );
        RtlFreeHeap(MspHeap, 0, OldPassword);
    }

    //
    // Free NewPassword if used. (Don't let password make it to page file)
    //

    if (NewPassword) {
        RtlZeroMemory( NewPassword, wcslen(NewPassword)*sizeof(WCHAR) );
        RtlFreeHeap(MspHeap, 0, NewPassword);
    }

    return Status;
}



NTSTATUS
MspChangePassword(
    IN OUT PUNICODE_STRING ComputerName,
    IN PUNICODE_STRING UserName,
    IN PUNICODE_STRING OldPassword,
    IN PUNICODE_STRING NewPassword,
    IN PLSA_CLIENT_REQUEST ClientRequest,
    IN BOOLEAN Impersonating,
    OUT PDOMAIN_PASSWORD_INFORMATION *DomainPasswordInfo,
    OUT PPOLICY_PRIMARY_DOMAIN_INFO *PrimaryDomainInfo OPTIONAL,
    OUT PBOOLEAN Authoritative
    )

/*++

Routine Description:

    This routine is called by MspLM20ChangePassword to change the password
    on the specified server.  The server may be either NT or Downlevel.

Arguments:

    ComputerName - Name of the target machine.  This name may or may not
        begin with two backslashes.

    UserName - Name of the user to change password for.

    OldPassword - Plaintext current password.

    NewPassword - Plaintext replacement password.

    ClientRequest - Is a pointer to an opaque data structure
        representing the client's request.

    DomainPasswordInfo - Password restriction information (returned only if
        status is STATUS_PASSWORD_RESTRICTION).

    PrimaryDomainInfo - DomainNameInformation (returned only if status is
        STATUS_BACKUP_CONTROLLER).

    Authoritative - Indicates that the error code is authoritative
        and it indicates that password changing should stop. If false,
        password changing should continue.


Return Value:

    STATUS_SUCCESS - Indicates the service completed successfully.

    STATUS_PASSWORD_RESTRICTION - Password changing is restricted.

--*/

{
    NTSTATUS Status;
    UNICODE_STRING UncComputerName;

    *Authoritative = TRUE;

    //
    // Ensure the server name is a UNC server name.
    //

    Status = MspAddBackslashesComputerName( ComputerName, &UncComputerName );

    if (!NT_SUCCESS(Status)) {
        KdPrint(("MspChangePassword: MspAddBackslashes..(%wZ) failed, status %x\n",
                 ComputerName, Status));
        return(Status);
    }


    //
    // Assume the Server is an NT server and try to change the password.
    //

    Status = MspChangePasswordSam(
                 &UncComputerName,
                 UserName,
                 OldPassword,
                 NewPassword,
                 ClientRequest,
                 Impersonating,
                 DomainPasswordInfo,
                 PrimaryDomainInfo,
                 Authoritative );

    //
    // If MspChangePasswordSam returns anything other than
    // STATUS_CANT_ACCESS_DOMAIN_INFO, it was able to connect
    // to the remote computer so we won't try downlevel.
    //

    if (Status == STATUS_CANT_ACCESS_DOMAIN_INFO) {
        NET_API_STATUS NetStatus;
        DWORD OptionsSupported;

        //
        // only if target machine doesn't support SAM protocol do we attempt
        // downlevel.
        // MspAddBackslashesComputerName() NULL terminates the buffer.
        //

        NetStatus = NetRemoteComputerSupports(
                     (LPWSTR)UncComputerName.Buffer,
                     SUPPORTS_RPC | SUPPORTS_LOCAL | SUPPORTS_SAM_PROTOCOL,
                     &OptionsSupported
                     );

        if( NetStatus == NERR_Success && !(OptionsSupported & SUPPORTS_SAM_PROTOCOL) ) {

            Status = MspChangePasswordDownlevel(
                        &UncComputerName,
                        UserName,
                        OldPassword,
                        NewPassword,
                        Authoritative );

        }
    }


    //
    // Free UncComputerName.Buffer if different from ComputerName.
    //

    if ( UncComputerName.Buffer != ComputerName->Buffer ) {
        RtlFreeHeap(MspHeap, 0, UncComputerName.Buffer);
    }

    return(Status);
}

⌨️ 快捷键说明

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