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

📄 nlpcache.c

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

    length = pEntry->DomainNameLength = NetbiosDomainName.Length;
    if (length) {
        RtlCopyMemory(dataptr, NetbiosDomainName.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->DnsDomainNameLength = DnsDomainName.Length;
    if (length) {
        RtlCopyMemory(dataptr, DnsDomainName.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->UpnLength = Upn.Length;
    if (length) {
        RtlCopyMemory(dataptr, Upn.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->EffectiveNameLength = AccountInfo->EffectiveName.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->EffectiveName.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->FullNameLength = AccountInfo->FullName.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->FullName.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->LogonScriptLength = AccountInfo->LogonScript.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->LogonScript.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->ProfilePathLength = AccountInfo->ProfilePath.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->ProfilePath.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->HomeDirectoryLength = AccountInfo->HomeDirectory.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->HomeDirectory.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->HomeDirectoryDriveLength = AccountInfo->HomeDirectoryDrive.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->HomeDirectoryDrive.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    pEntry->UserId = AccountInfo->UserId;
    pEntry->PrimaryGroupId = AccountInfo->PrimaryGroupId;

    length = pEntry->GroupCount = AccountInfo->GroupCount;
    length *= sizeof(GROUP_MEMBERSHIP);
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->GroupIds, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    length = pEntry->LogonDomainNameLength = AccountInfo->LogonDomainName.Length;
    if (length) {
        RtlCopyMemory(dataptr, AccountInfo->LogonDomainName.Buffer, length);
        dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));
    }

    if (AccountInfo->UserFlags & LOGON_EXTRA_SIDS) {
        length = pEntry->SidCount = AccountInfo->SidCount;
        length *= sizeof(ULONG);
        if (length) {
            ULONG i, sidLength;
            PULONG sidAttributes = (PULONG) dataptr;

            dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));

            //
            // Now copy over all the SIDs
            //

            for (i = 0; i < AccountInfo->SidCount ; i++ ) {
                sidAttributes[i] = AccountInfo->ExtraSids[i].Attributes;
                sidLength = RtlLengthSid(AccountInfo->ExtraSids[i].Sid);
                RtlCopySid(sidLength,(PSID) dataptr,AccountInfo->ExtraSids[i].Sid);
                dataptr = ROUND_UP_POINTER(dataptr + sidLength, sizeof(ULONG));
            }
            pEntry->SidLength = (ULONG) (dataptr - (PCHAR) sidAttributes);
        } else {
            pEntry->SidLength = 0;
        }
    } else {
        pEntry->SidCount = 0;
        pEntry->SidLength = 0;
    }

    pEntry->LogonDomainIdLength = (USHORT) RtlLengthSid(AccountInfo->LogonDomainId);

    NtStatus = RtlCopySid(pEntry->LogonDomainIdLength,
                          (PSID)dataptr,
                          AccountInfo->LogonDomainId
                          );
    ASSERT(NT_SUCCESS(NtStatus));
    dataptr = ROUND_UP_POINTER(dataptr+length, sizeof(ULONG));

    //
    // fill in randomkey for this cache entry.
    //

    SspGenerateRandomBits( pEntry->RandomKey, sizeof(pEntry->RandomKey) );

    *ppCacheEntry = pEntry;

#if DBG
    if (DumpCacheInfo) {
        DbgPrint("BuildCacheEntry:\n");
        DumpCacheEntry(999,pEntry);
    }
#endif
    return STATUS_SUCCESS;
}


NTSTATUS
NlpOpenCache( VOID )

/*++

Routine Description:

    Opens the registry node for read or write (depending on Switch) and opens
    the secret storage in the same mode.  If successful, the NlpCacheHandle
    is valid.

Arguments:

Return Value:

    NTSTATUS
        Success = STATUS_SUCCESS
                    NlpCacheHandle contains handle to use for reading/writing
                    registry

        Failure =

--*/

{
    NTSTATUS NtStatus;
    ULONG Disposition;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING ObjectName;

    ObjectName.Length = ObjectName.MaximumLength = CACHE_NAME_SIZE;
    ObjectName.Buffer = CACHE_NAME;

    InitializeObjectAttributes(&ObjectAttributes,
                                &ObjectName,
                                OBJ_CASE_INSENSITIVE,
                                0,      // RootDirectory
                                NULL    // BUGBUG - put security descriptor here
                                );
    NtStatus = NtCreateKey(&NlpCacheHandle,
                           (KEY_WRITE | KEY_READ),
                           &ObjectAttributes,
                           CACHE_TITLE_INDEX,
                           NULL,   // class name
                           0,      // create options
                           &Disposition
                           );

    return NtStatus;
}


VOID
NlpCloseCache( VOID )

/*++

Routine Description:

    Closes handles opened by NlpOpenCache

Arguments:

    None.

Return Value:

    None.

--*/

{
#if DBG
    NTSTATUS NtStatus;

    if (DumpCacheInfo) {
        DbgPrint("CloseCache: Closing NlpCacheHandle (%#08x)\n", NlpCacheHandle);
    }

    if (IS_VALID_HANDLE(NlpCacheHandle)) {
        NtStatus = NtClose(NlpCacheHandle);
        if (DumpCacheInfo) {
            DbgPrint("CloseCache: NtClose returns %#08x\n", NtStatus);
        }
        ASSERT(NT_SUCCESS(NtStatus));
        INVALIDATE_HANDLE(NlpCacheHandle);
    }
#else
    if (IS_VALID_HANDLE(NlpCacheHandle)) {
        NtClose(NlpCacheHandle);
        INVALIDATE_HANDLE(NlpCacheHandle);
    }
#endif
}


NTSTATUS
NlpOpenSecret(
    IN  ULONG   Index
    )

/*++

Routine Description:

    Opens a cache entry's secret storage object for read (in order to LsaQuerySecret) and
    write (in order to LsaSetSecret).  If successful, the handle value
    is placed in the global variable NlpSecretHandle.

    If the secret does not exist, it will be created.


Arguments:

    Index - The index of the entry being opened.  This is used to build
        a name of the object.

Return Value:

    NTSTATUS
        Success = STATUS_SUCCESS
                    NlpSecretHandle can be used to read/write secret storage

        Failure =

--*/

{
    NTSTATUS
        NtStatus;

    UNICODE_STRING
        ValueName;

    WCHAR
        NameBuffer[32];


    //
    // Close previous handle if necessary
    //

    if (IS_VALID_HANDLE(NlpSecretHandle)) {
        I_LsarClose( &NlpSecretHandle );
    }


    ValueName.Buffer = &NameBuffer[0];
    ValueName.MaximumLength = 32;
    ValueName.Length = 0;
    NlpMakeCacheEntryName( Index, &ValueName );




    NtStatus = I_LsarOpenSecret(NlpLsaHandle,
                             (PLSAPR_UNICODE_STRING) &ValueName,
                             SECRET_QUERY_VALUE | SECRET_SET_VALUE,
                             &NlpSecretHandle
                             );

    if (!NT_SUCCESS(NtStatus)) {
        if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND) {
            NtStatus = I_LsarCreateSecret(NlpLsaHandle,
                                       (PLSAPR_UNICODE_STRING) &ValueName,
                                       SECRET_SET_VALUE | SECRET_QUERY_VALUE,
                                       &NlpSecretHandle
                                       );
            if (!NT_SUCCESS(NtStatus)) {
                INVALIDATE_HANDLE(NlpSecretHandle);
            }
        } else {
            INVALIDATE_HANDLE(NlpSecretHandle);
        }
    }
    return(NtStatus);
}


VOID
NlpCloseSecret( VOID )

/*++

Routine Description:

    Closes the handles opened via NlpOpenSecret

Arguments:

    None.

Return Value:

    None.

--*/

{
    NTSTATUS
        NtStatus;

    if (IS_VALID_HANDLE(NlpSecretHandle)) {
        NtStatus = I_LsarClose(&NlpSecretHandle);
#if DBG
        if (DumpCacheInfo) {
            DbgPrint("CloseSecret: LsaClose returns %#08x\n", NtStatus);
        }
#endif
        ASSERT(NT_SUCCESS(NtStatus));
        INVALIDATE_HANDLE(NlpSecretHandle);
    }
}


NTSTATUS
NlpWriteSecret(
    IN  PLSAPR_CR_CIPHER_VALUE NewSecret,
    IN  PLSAPR_CR_CIPHER_VALUE OldSecret
    )

/*++

Routine Description:

    Writes the password (and optionally the previous password) to the LSA
    secret storage

Arguments:

    NewSecret   - pointer to UNICODE_STRING containing current password
    OldSecret   - pointer to UNICODE_STRING containing previous password

Return Value:

    NTSTATUS
        Success =
        Failure =

--*/

{

    return I_LsarSetSecret(NlpSecretHandle, NewSecret, OldSecret);
}


NTSTATUS
NlpReadSecret(
    OUT PLSAPR_CR_CIPHER_VALUE * NewSecret,
    OUT PLSAPR_CR_CIPHER_VALUE * OldSecret
    )

/*++

Routine Description:

    Reads the new and old secrets (UNICODE_STRINGs) for the
    currently open LSA secret

    The Lsa routine returns us pointers to UNICODE strings

Arguments:

    NewSecret   - pointer to returned pointer to UNICODE_STRING containing
                  most recent password (if any)

    OldSecret   - pointer to returned pointer to UNICODE_STRING containing
                  previous password (if any)

Return Value:

    NTSTATUS
        Success
        Failure

--*/

{
    NTSTATUS
        NtStatus;

    LARGE_INTEGER
        NewTime,
        OldTime;



    NtStatus = I_LsarQuerySecret(NlpSecretHandle,
                              NewSecret,
                              &NewTime,
                              OldSecret,
                              &OldTime
                              );



#if DBG
    {
        char newNt[80];
        char newLm[80];
        char oldNt[80];
        char oldLm[80];

        if (DumpCacheInfo) {
            DbgPrint("NlpReadSecret: NewSecret.Nt = \"%s\"\n"
                     "            NewSecret.Lm = \"%s\"\n"
                     "            OldSecret.Nt = \"%s\"\n"
                     "            OldSecret.Lm = \"%s\"\n",
                     *NewSecret
                        ? DumpOwfPasswordToString(newNt, (PLM_OWF_PASSWORD)((*NewSecret)->Buffer))
                        : "",
                     *NewSecret
                        ? DumpOwfPasswordToString(newLm, (PLM_OWF_PASSWORD)((*NewSecret)->Buffer)+1)
                        : "",
                     *OldSecret
                        ? DumpOwfPasswordToString(oldNt, (PLM_OWF_PASSWORD)((*OldSecret)->Buffer))
                        : "",
                     *OldSecret
                        ? DumpOwfPasswordToString(oldLm, (PLM_OWF_PASSWORD)((*OldSecret)->Buffer)+1)
                        : ""
                     );
        }
    }
#endif

    return NtStatus;
}


NTSTATUS
NlpComputeSaltedHashedPassword(
    OUT PNT_OWF_PASSWORD SaltedOwfPassword,
    IN PNT_OWF_PASSWORD OwfPassword,
    IN PUNICODE_STRING UserName
    )

/*++

Routine Description:

    Computes the salted hash of a password by concatenating the user name
    with the OWF and computing the OWF of the combination.

Arguments:

    SaltedOwfPassword - receives the LM or NT salted password/
    OwfPassword - Contains the NT or LM owf password.
    UserName - Contains the name of the user, used for salt.

Return Value:

    NTSTATUS
        Success = STATUS_SUCCESS
                    Passwords created OK

        Failure = STATUS_NO_MEMORY
                    Not enough storage to create Passwords

--*/
{
    NTSTATUS Status;
    UNICODE_STRING TempString;
    UNICODE_STRING LowerUserName;

    //
    // Compute the lower case user name.
    //

    Status = RtlDowncaseUnicodeString( &LowerUserName,
                                       UserName,
                                       TRUE );

    if ( !NT_SUCCESS(Status)) {
        return Status;
    }


    //
    // Build a string that is a concatenation of the OWF and LowerCase username.
    //

    TempString.Length = TempString.MaximumLength = LowerUserName.Length + sizeof(NT_OWF_PASSWORD);
    TempString.Buffer = AllocateFromHeap( TempString.Length );
    if (TempString.Buffer == NULL) {
        RtlFreeUnicodeString( &LowerUserName );
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    Rt

⌨️ 快捷键说明

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