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

📄 nlpcache.c

📁 安全支持提供器接口(SSPI)源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                            &CacheEntry->CachePasswords,
                            &AccountInfo->EffectiveName,
                            &LogonInfo->NtOwfPassword,
                            &LogonInfo->LmOwfPassword
                            );

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



    //
    // encrypt sensitive portions of the cache entry.
    //

    NtStatus = NlpEncryptCacheEntry(CacheEntry, EntrySize);

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


    ENTER_CACHE();

    //
    // See if this entry already exists in the cache.
    // If so, use the same index.
    //

    NtStatus = NlpReadCacheEntry(&LogonInfo->Identity.LogonDomainName,
                                 &LogonInfo->Identity.UserName,
                                  &Index,
                                  &CacheEntryExisting,
                                  &EntrySizeExisting
                                  );

    //
    // If we didn't find an entry, then we need to allocate an
    // entry.
    //

    if (!NT_SUCCESS(NtStatus)) {

        NlpGetFreeEntryIndex( &Index );

        CacheEntryExisting = NULL;

    } else {

        //
        // We already have an entry for this user.
        // Discard the structure we got back but
        // use the same index.
        // Note: structure discarded outside cache lock.
        //

        // TODO: check if existing entry matches new built entry.
        // if so, avoid write.
    }


    //
    // now, write the entry out...
    //

    NtStatus = NlpWriteCacheEntry(Index, CacheEntry, EntrySize);


    if (NT_SUCCESS(NtStatus)) {
        NlpCteTable[Index].Time = CacheEntry->Time;
        NlpAddEntryToActiveList( Index );
    }

    LEAVE_CACHE();


Cleanup:


    if( CacheEntry ) {
        ZeroMemory( CacheEntry, EntrySize );
        FreeCacheEntry( CacheEntry );
    }

    if( CacheEntryExisting ) {
        ZeroMemory( CacheEntryExisting, EntrySizeExisting );
        FreeCacheEntry( CacheEntryExisting );
    }

    return(NtStatus);
}



NTSTATUS
NlpAddSupplementalCacheData(
    IN      PVOID SupplementalCacheData,
    IN      ULONG SupplementalCacheDataLength,
    IN OUT  PLOGON_CACHE_ENTRY *ppCacheEntry,
    IN OUT  PULONG pEntryLength
    )

/*++

Routine Description:

    Extends the supplied LOGON_CACHE_ENTRY with opaque authentication package
    SupplementalCacheData (eg: smart-card logon cache info).

Return Value:

    NTSTATUS
        Success = STATUS_SUCCESS

        Failure =

--*/

{
    PLOGON_CACHE_ENTRY NewCacheEntry = NULL;

    if( (*ppCacheEntry)->Revision < NLP_CACHE_REVISION_NT_5_0 ) {
        return STATUS_SUCCESS;
    }

    (*ppCacheEntry)->SupplementalCacheDataLength = SupplementalCacheDataLength;
    (*ppCacheEntry)->SupplementalCacheDataOffset = *pEntryLength;


    if( SupplementalCacheData == NULL || SupplementalCacheDataLength == 0 ) {
        return STATUS_SUCCESS;
    }


    //
    // allocate new entry, and copy existing entry + supplemental data to end.
    //

    NewCacheEntry = AllocateCacheEntry( *pEntryLength + SupplementalCacheDataLength );

    if( NewCacheEntry == NULL ) {
        return STATUS_NO_MEMORY;
    }

    CopyMemory( NewCacheEntry, *ppCacheEntry, *pEntryLength );
    CopyMemory( ((PBYTE)(NewCacheEntry) + *pEntryLength),
                SupplementalCacheData,
                SupplementalCacheDataLength
                );

    ZeroMemory( *ppCacheEntry, *pEntryLength );
    FreeCacheEntry( *ppCacheEntry );

    *ppCacheEntry = NewCacheEntry;
    *pEntryLength += SupplementalCacheDataLength;

    return STATUS_SUCCESS;
}


NTSTATUS
NlpDeleteCacheEntry(
    IN  PNETLOGON_INTERACTIVE_INFO LogonInfo
    )

/*++

Routine Description:

    Deletes a user account from the local user account cache, if the corresponding
    entry can be found. We actually just null out the current contents instead of
    destroying the storage - this should save us some time when we next come to
    add an entry to the cache

Arguments:

    LogonInfo   - pointer to NETLOGON_INTERACTIVE_INFO structure which contains
                  the domain name, user name and password for this user

Return Value:

    NTSTATUS
        Success = STATUS_SUCCESS

        Failure =

--*/

{
    NTSTATUS
        NtStatus;

    PLOGON_CACHE_ENTRY
        CacheEntry = NULL;

    ULONG
        EntrySize,
        Index;


    if (NlpInitializationNotYetPerformed) {
        NtStatus = NlpInternalCacheInitialize();
        if (!NT_SUCCESS(NtStatus)) {
            return(NtStatus);
        }
    }


    if (NlpCacheControl.Entries == 0) {
        return(STATUS_SUCCESS);
    }

    ENTER_CACHE();

    //
    // See if this entry exists in the cache.
    //

    NtStatus = NlpReadCacheEntry( &LogonInfo->Identity.LogonDomainName,
                                  &LogonInfo->Identity.UserName,
                                  &Index,
                                  &CacheEntry,
                                  &EntrySize
                                  );

    //
    // If we didn't find an entry, then there is nothing to do.
    //

    if (!NT_SUCCESS(NtStatus)) {
        LEAVE_CACHE();
        return(STATUS_SUCCESS);
    }

    //
    // Mark it as invalid.
    //

    CacheEntry->Valid = FALSE;

    NtStatus = NlpWriteCacheEntry( Index, CacheEntry, EntrySize );

    if (NT_SUCCESS(NtStatus)) {

        //
        // Put the CTE entry on the inactive list.
        //

        NlpAddEntryToInactiveList( Index );
    }


    LEAVE_CACHE();


    //
    // Free the structure returned from NlpReadCacheEntry()
    //

    if( CacheEntry ) {
        ZeroMemory( CacheEntry, EntrySize );
        FreeToHeap( CacheEntry );
    }


    return(NtStatus);
}


VOID
NlpChangeCachePassword(
    IN PUNICODE_STRING DomainName,
    IN PUNICODE_STRING UserName,
    IN PLM_OWF_PASSWORD LmOwfPassword,
    IN PNT_OWF_PASSWORD NtOwfPassword
    )

/*++

Routine Description:

    Update a cached password to the specified value, if we have
    the specified account cached.

Arguments:


    DomainName - The name of the domain in which the account exists.

    UserName - The name of the account whose password is to be changed.

    LmOwfPassword - The new LM compatible password.

    NtOwfPassword - The new NT compatible password.

Return Value:

    None.

--*/

{
    NTSTATUS
        NtStatus;

    PLOGON_CACHE_ENTRY
        CacheEntry = NULL;

    ULONG
        EntrySize,
        Index;

    PLSAPR_CR_CIPHER_VALUE
        CurrentSecret = NULL,
        OldSecret = NULL;

    LSAPR_CR_CIPHER_VALUE
        Passwords;


#if DBG
    if (DumpCacheInfo) {
        DbgPrint("NlpChangeCachePassword\n");
    }
#endif

    if (NlpInitializationNotYetPerformed) {
        NtStatus = NlpInternalCacheInitialize();
        if (!NT_SUCCESS(NtStatus)) {
            return;
        }
    }


    if (NlpCacheControl.Entries == 0) {
        return;
    }

    ENTER_CACHE();


    NtStatus = NlpReadCacheEntry( DomainName,
                                  UserName,
                                  &Index,
                                  &CacheEntry,
                                  &EntrySize);

    if(!NT_SUCCESS( NtStatus) ) {
        LEAVE_CACHE();
        return ;
    }


    if( CacheEntry->Revision >= NLP_CACHE_REVISION_NT_5_0 ) {
        UNICODE_STRING CachedUser;

        CachedUser.Length =
            CachedUser.MaximumLength = CacheEntry->UserNameLength;
        CachedUser.Buffer = (PWSTR) ((PBYTE) CacheEntry + sizeof(LOGON_CACHE_ENTRY));

        NtStatus = NlpMakeSecretPasswordNT5( &CacheEntry->CachePasswords,
                                          &CachedUser,
                                          NtOwfPassword,
                                          LmOwfPassword );


        if(NT_SUCCESS(NtStatus)) {

            //
            // encrypt the entry...
            //

            NtStatus = NlpEncryptCacheEntry( CacheEntry, EntrySize );
        }

        if(NT_SUCCESS( NtStatus )) {

            //
            // now, write the entry out...
            //

            NtStatus = NlpWriteCacheEntry(Index, CacheEntry, EntrySize);

#ifdef DBG
            if(DumpCacheInfo) {
                if( NT_SUCCESS( NtStatus ) ) {
                    DbgPrint("NlpChangeCachePassword: SUCCEED write NT5 version cache entry.\n");
                } else {
                    DbgPrint("NlpChangeCachePassword: FAIL write NT5 version cache entry.\n");
                }
            }
#endif

        }

    } else {

        NtStatus = NlpOpenSecret( Index );
        if (NT_SUCCESS(NtStatus)) {

            NtStatus = NlpReadSecret(&CurrentSecret, &OldSecret);
            if (NT_SUCCESS(NtStatus)) {
                UNICODE_STRING CachedUser;

                //
                // Grab the various strings from the cache entry.
                //
                ASSERT( CacheEntry->Revision >= NLP_CACHE_REVISION_NT_1_0B );

                CachedUser.Length =
                    CachedUser.MaximumLength = CacheEntry->UserNameLength;
                CachedUser.Buffer = (PWSTR) ((PBYTE) CacheEntry + sizeof(LOGON_CACHE_ENTRY_NT_4_SP4));

                NtStatus = NlpMakeSecretPassword( &Passwords,
                                                  &CachedUser,
                                                  NtOwfPassword,
                                                  LmOwfPassword );

                if (NT_SUCCESS(NtStatus)) {
                    NtStatus = NlpWriteSecret(&Passwords, CurrentSecret);

                    //
                    // free the buffer allocated to store the passwords
                    //

                    FreeToHeap(Passwords.Buffer);
                }

                //
                // free strings returned by NlpReadSecret
                //

                if (CurrentSecret) {
                    MIDL_user_free(CurrentSecret);
                }
                if (OldSecret) {
                    MIDL_user_free(OldSecret);
                }

            }
        }

    }

    LEAVE_CACHE();


    //
    // free structure allocated by NlpReadCacheEntry
    //

    if( CacheEntry ) {
        ZeroMemory( CacheEntry, EntrySize );
        FreeToHeap(CacheEntry);
    }

    return;
}


////////////////////////////////////////////////////////////////////////
//                                                                    //
// Services Internal to this module                                   //
//                                                                    //
////////////////////////////////////////////////////////////////////////


NTSTATUS
NlpInternalCacheInitialize(
    VOID
    )

/*++

Routine Description:

    This routine is called to initialize cached logon processing.

    This routine will automatically adjust the size of the logon
    cache if necessary to accomodate a new user-specified length
    (specified in the Winlogon part of the registry).

    NOTE: If called too early, this routine won't be able to call
          LSA's RPC routines.  In this case, initialization is
          defered until later.

Arguments:

    None.

Return Value:

    NTSTATUS

--*/

{

    NTSTATUS
        NtStatus;

    OBJECT_ATTRIBUTES
        ObjectAttributes;

// DbgPrint("\n\n\n     REMEMBER TO TAKE THIS BREAKPOINT OUT BEFORE CHECKIN.\n\n\n");
// DumpCacheInfo = 1;   // Remember to take this out too !!!!!!
// DbgBreakPoint();     // Remember to take this out before checking

#if DBG
    if (DumpCacheInfo) {
        DbgPrint("NlpCacheInitialize\n");
    }
#endif


    //
    // Upon return from this routine, if logon caching is enabled,
    // the following will be true:

⌨️ 快捷键说明

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