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

📄 nlp.c

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

        //
        // Kludge: Pass back UserParameters in HomeDirectoryDrive since we
        // can't change the NETLOGON_VALIDATION_SAM_INFO structure between
        // releases NT 1.0 and NT 1.0A. HomeDirectoryDrive was NULL for release 1.0A
        // so we'll use that field.
        //

        NlpPutClientString( &ClientBufferDesc,
                            &LocalProfile->UserParameters,
                            &NlpUser->HomeDirectoryDrive );

    }

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

    Status = NlpFlushClientBuffer( &ClientBufferDesc,
                                   ProfileBuffer );

Cleanup:

    //
    // If the copy wasn't successful,
    //  cleanup resources we would have returned to the caller.
    //

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

    // Save the status for subauth logons

    if (NT_SUCCESS(Status) && !NT_SUCCESS(SubAuthStatus))
    {
        Status = SubAuthStatus;
    }

    return Status;

}


PSID
NlpMakeDomainRelativeSid(
    IN PSID DomainId,
    IN ULONG RelativeId
    )

/*++

Routine Description:

    Given a domain Id and a relative ID create the corresponding SID allocated
    from the LSA heap.

Arguments:

    DomainId - The template SID to use.

    RelativeId - The relative Id to append to the DomainId.

Return Value:

    Sid - Returns a pointer to a buffer allocated from the LsaHeap
            containing the resultant Sid.

--*/
{
    UCHAR DomainIdSubAuthorityCount;
    ULONG Size;
    PSID Sid;

    //
    // Allocate a Sid which has one more sub-authority than the domain ID.
    //

    DomainIdSubAuthorityCount = *(RtlSubAuthorityCountSid( DomainId ));
    Size = RtlLengthRequiredSid(DomainIdSubAuthorityCount+1);

    if ((Sid = (*Lsa.AllocateLsaHeap)( Size )) == NULL ) {
        return NULL;
    }

    //
    // Initialize the new SID to have the same inital value as the
    // domain ID.
    //

    if ( !NT_SUCCESS( RtlCopySid( Size, Sid, DomainId ) ) ) {
        (*Lsa.FreeLsaHeap)( Sid );
        return NULL;
    }

    //
    // Adjust the sub-authority count and
    //  add the relative Id unique to the newly allocated SID
    //

    (*(RtlSubAuthorityCountSid( Sid ))) ++;
    *RtlSubAuthoritySid( Sid, DomainIdSubAuthorityCount ) = RelativeId;


    return Sid;
}



PSID
NlpCopySid(
    IN  PSID * Sid
    )

/*++

Routine Description:

    Given a SID allocatees space for a new SID from the LSA heap and copies
    the original SID.

Arguments:

    Sid - The original SID.

Return Value:

    Sid - Returns a pointer to a buffer allocated from the LsaHeap
            containing the resultant Sid.

--*/
{
    PSID NewSid;
    ULONG Size;

    Size = RtlLengthSid( Sid );



    if ((NewSid = (*Lsa.AllocateLsaHeap)( Size )) == NULL ) {
        return NULL;
    }


    if ( !NT_SUCCESS( RtlCopySid( Size, NewSid, Sid ) ) ) {
        (*Lsa.FreeLsaHeap)( NewSid );
        return NULL;
    }


    return NewSid;
}

//+-------------------------------------------------------------------------
//
//  Function:   NlpMakeTokenInformationV2
//
//  Synopsis:   This routine makes copies of all the pertinent
//              information from the UserInfo and generates a
//              LSA_TOKEN_INFORMATION_V2 data structure.
//
//  Effects:
//
//  Arguments:
//
//    UserInfo - Contains the validation information which is
//        to be copied into the TokenInformation.
//
//    TokenInformation - Returns a pointer to a properly Version 1 token
//        information structures.  The structure and individual fields are
//        allocated properly as described in ntlsa.h.
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS - Indicates the service completed successfully.
//
//              STATUS_INSUFFICIENT_RESOURCES -  This error indicates that
//                      the logon could not be completed because the client
//                      does not have sufficient quota to allocate the return
//                      buffer.
//
//  Notes:      stolen back from from kerberos\client2\krbtoken.cxx.c:KerbMakeTokenInformationV1
//
//
//--------------------------------------------------------------------------


NTSTATUS
NlpMakeTokenInformationV2(
    IN  PNETLOGON_VALIDATION_SAM_INFO2 ValidationInfo,
    OUT PLSA_TOKEN_INFORMATION_V2 *TokenInformation
    )
{
    PNETLOGON_VALIDATION_SAM_INFO3 UserInfo = (PNETLOGON_VALIDATION_SAM_INFO3) ValidationInfo;
    NTSTATUS Status;
    PLSA_TOKEN_INFORMATION_V2 V2 = NULL;
    ULONG Size, i;
    SID LocalSystemSid = {SID_REVISION,1,SECURITY_NT_AUTHORITY,SECURITY_LOCAL_SYSTEM_RID};
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    DWORD NumGroups = 0;
    PBYTE CurrentSid = NULL;
    ULONG SidLength = 0;

    //
    // Allocate the structure itself
    //

    Size = (ULONG)sizeof(LSA_TOKEN_INFORMATION_V2);

    //
    // Allocate an array to hold the groups
    //

    Size += sizeof(TOKEN_GROUPS);


    // Add room for groups passed as RIDS
    NumGroups = UserInfo->GroupCount;
    if(UserInfo->GroupCount)
    {
        Size += UserInfo->GroupCount * (RtlLengthSid(UserInfo->LogonDomainId) + sizeof(ULONG));
    }

    //
    // If there are extra SIDs, add space for them
    //

    if (UserInfo->UserFlags & LOGON_EXTRA_SIDS) {
        ULONG i = 0;
        NumGroups += UserInfo->SidCount;

        // Add room for the sid's themselves
        for(i=0; i < UserInfo->SidCount; i++)
        {
            Size += RtlLengthSid(UserInfo->ExtraSids[i].Sid);
        }
    }

    //
    // If there are resource groups, add space for them
    //
    if (UserInfo->UserFlags & LOGON_RESOURCE_GROUPS) {

        NumGroups += UserInfo->ResourceGroupCount;

        if ((UserInfo->ResourceGroupCount != 0) &&
            ((UserInfo->ResourceGroupIds == NULL) ||
             (UserInfo->ResourceGroupDomainSid == NULL)))
        {
            Status = STATUS_INVALID_PARAMETER;
            goto Cleanup;
        }
        // Allocate space for the sids
        if(UserInfo->ResourceGroupCount)
        {
            Size += UserInfo->ResourceGroupCount * (RtlLengthSid(UserInfo->ResourceGroupDomainSid) + sizeof(ULONG));
        }

    }


    if( UserInfo->UserId )
    {
        // Size of the user sid and the primary group sid.
        Size += 2*(RtlLengthSid(UserInfo->LogonDomainId) + sizeof(ULONG));
    }
    else
    {
        if ( UserInfo->SidCount <= 0 ) {

            Status = STATUS_INSUFFICIENT_LOGON_INFO;
            goto Cleanup;
        }

        // Size of the primary group sid.
        Size += (RtlLengthSid(UserInfo->LogonDomainId) + sizeof(ULONG));
    }


    Size += (NumGroups - ANYSIZE_ARRAY)*sizeof(SID_AND_ATTRIBUTES);


    V2 = (PLSA_TOKEN_INFORMATION_V2) (*Lsa.AllocateLsaHeap)( Size );
    if ( V2 == NULL ) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(
        V2,
        Size
        );

    V2->Groups = (PTOKEN_GROUPS)(V2+1);
    V2->Groups->GroupCount = 0;
    CurrentSid = (PBYTE)&V2->Groups->Groups[NumGroups];

    OLD_TO_NEW_LARGE_INTEGER( UserInfo->KickOffTime, V2->ExpirationTime );


 
    //
    // If the UserId is non-zero, then it contians the users RID.
    //

    if ( UserInfo->UserId ) {
        V2->User.User.Sid = (PSID)CurrentSid;
        CurrentSid += NlpCopyDomainRelativeSid((PSID)CurrentSid, UserInfo->LogonDomainId, UserInfo->UserId);
    }

    //
    // Make a copy of the primary group (a required field).
    //
    V2->PrimaryGroup.PrimaryGroup = (PSID)CurrentSid;
    CurrentSid += NlpCopyDomainRelativeSid((PSID)CurrentSid, UserInfo->LogonDomainId, UserInfo->PrimaryGroupId );




    //
    // Copy over all the groups passed as RIDs
    //

    for ( i=0; i < UserInfo->GroupCount; i++ ) {

        V2->Groups->Groups[V2->Groups->GroupCount].Attributes = UserInfo->GroupIds[i].Attributes;

        V2->Groups->Groups[V2->Groups->GroupCount].Sid = (PSID)CurrentSid;
        CurrentSid += NlpCopyDomainRelativeSid((PSID)CurrentSid, UserInfo->LogonDomainId, UserInfo->GroupIds[i].RelativeId);

        V2->Groups->GroupCount++;
    }


    //
    // Add in the extra SIDs
    //

    if (UserInfo->UserFlags & LOGON_EXTRA_SIDS) {

        ULONG index = 0;
        //
        // If the user SID wasn't passed as a RID, it is the first
        // SID.
        //

        if ( !V2->User.User.Sid ) {
            V2->User.User.Sid = (PSID)CurrentSid;
            SidLength = RtlLengthSid(UserInfo->ExtraSids[index].Sid);
            RtlCopySid(SidLength, (PSID)CurrentSid, UserInfo->ExtraSids[index].Sid);

            CurrentSid += SidLength;
            index++;
        }

        //
        // Copy over all additional SIDs as groups.
        //

        for ( ; index < UserInfo->SidCount; index++ ) {

            V2->Groups->Groups[V2->Groups->GroupCount].Attributes =
                UserInfo->ExtraSids[index].Attributes;

            V2->Groups->Groups[V2->Groups->GroupCount].Sid= (PSID)CurrentSid;
            SidLength = RtlLengthSid(UserInfo->ExtraSids[index].Sid);
            RtlCopySid(SidLength, (PSID)CurrentSid, UserInfo->ExtraSids[index].Sid);

            CurrentSid += SidLength;

            V2->Groups->GroupCount++;
        }
    }

    //
    // Check to see if any resouce groups exist
    //

    if (UserInfo->UserFlags & LOGON_RESOURCE_GROUPS) {


        for ( i=0; i < UserInfo->ResourceGroupCount; i++ ) {

            V2->Groups->Groups[V2->Groups->GroupCount].Attributes = UserInfo->ResourceGroupIds[i].Attributes;

            V2->Groups->Groups[V2->Groups->GroupCount].Sid= (PSID)CurrentSid;
            CurrentSid += NlpCopyDomainRelativeSid((PSID)CurrentSid, UserInfo->ResourceGroupDomainSid, UserInfo->ResourceGroupIds[i].RelativeId);

            V2->Groups->GroupCount++;
        }
    }

    ASSERT( ((PBYTE)V2 + Size) == CurrentSid );


    if (!V2->User.User.Sid) {

        Status = STATUS_INSUFFICIENT_LOGON_INFO;
        goto Cleanup;
    }

    //
    // There are no default privileges supplied.
    // We don't have an explicit owner SID.
    // There is no default DACL.
    //

    V2->Privileges = NULL;
    V2->Owner.Owner = NULL;
    V2->DefaultDacl.DefaultDacl = NULL;

    //
    // Return the Validation Information to the caller.
    //

    *TokenInformation = V2;
    return STATUS_SUCCESS;

    //
    // Deallocate any memory we've allocated
    //

Cleanup:

    (*Lsa.FreeLsaHeap)( V2 );

    return Status;

}



VOID
NlpPutOwfsInPrimaryCredential(
    IN PUNICODE_STRING CleartextPassword,
    OUT PMSV1_0_PRIMARY_CREDENTIAL Credential
    )
/*++

Routine Description:

    This routine puts the OWFs for the specified clear password into
    the passed in Credential structure.

Arguments:

    CleartextPassword - Is a string containing the user's cleartext password.
        The password may be up to 255 characters long and contain any
        UNICODE value.

    Credential - A pointer to the credential to update.

Return Value:

    STATUS_SUCCESS - Indicates the service completed successfully.

    STATUS_QUOTA_EXCEEDED -  This error indicates that the logon
        could not be completed because the client does not have
        sufficient quota to allocate the return buffer.


--*/

{
    NTSTATUS Status;
    CHAR LmPassword[LM20_PWLEN+1];
    BOOLEAN LmPasswordPresent;
    STRING AnsiCleartextPassword;


    //
    // Compute the Ansi version to the Cleartext password.
    //
    //  The Ansi version of the Cleartext password is at most 14 bytes long,
    //      exists in a trailing zero filled 15 byte buffer,
    //      is uppercased.
    //

    AnsiCleartextPassword.Buffer = LmPassword;
    AnsiCleartextPassword.MaximumLength = sizeof(LmPassword);

    RtlZeroMemory( &LmPassword, sizeof(LmPassword) );

    Status = RtlUpcaseUnicodeStringToOemString(

⌨️ 快捷键说明

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