683 lines
17 KiB
C
683 lines
17 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1987-1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
rgroups.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Routines to expand transitive group membership.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Mike Swift (mikesw) 8-May-1998
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User mode only.
|
|||
|
Contains NT-specific code.
|
|||
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
//
|
|||
|
// Common include files.
|
|||
|
//
|
|||
|
|
|||
|
#include "logonsrv.h" // Include files common to entire service
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
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 = MIDL_user_allocate( Size )) == NULL ) {
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( !NT_SUCCESS( RtlCopySid( Size, NewSid, Sid ) ) ) {
|
|||
|
MIDL_user_free( NewSid );
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return NewSid;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NlpBuildPacSidList(
|
|||
|
IN PNETLOGON_VALIDATION_SAM_INFO4 UserInfo,
|
|||
|
OUT PSAMPR_PSID_ARRAY Sids
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Given the validation information for a user, expands the group member-
|
|||
|
ships and user id into a list of sids
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
UserInfo - user's validation information
|
|||
|
Sids - receives an array of all the user's group sids and user id
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
|
|||
|
STATUS_INSUFFICIENT_RESOURCES - there wasn't enough memory to
|
|||
|
create the list of sids.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
ULONG Size = 0, i;
|
|||
|
|
|||
|
Sids->Count = 0;
|
|||
|
Sids->Sids = NULL;
|
|||
|
|
|||
|
|
|||
|
if (UserInfo->UserId != 0) {
|
|||
|
Size += sizeof(SAMPR_SID_INFORMATION);
|
|||
|
}
|
|||
|
|
|||
|
Size += UserInfo->GroupCount * (ULONG)sizeof(SAMPR_SID_INFORMATION);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If there are extra SIDs, add space for them
|
|||
|
//
|
|||
|
|
|||
|
if (UserInfo->UserFlags & LOGON_EXTRA_SIDS) {
|
|||
|
Size += UserInfo->SidCount * (ULONG)sizeof(SAMPR_SID_INFORMATION);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Sids->Sids = (PSAMPR_SID_INFORMATION) MIDL_user_allocate( Size );
|
|||
|
|
|||
|
if ( Sids->Sids == NULL ) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
Sids->Sids,
|
|||
|
Size
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Start copying SIDs into the structure
|
|||
|
//
|
|||
|
|
|||
|
i = 0;
|
|||
|
|
|||
|
//
|
|||
|
// If the UserId is non-zero, then it contians the users RID.
|
|||
|
//
|
|||
|
|
|||
|
if ( UserInfo->UserId ) {
|
|||
|
NetStatus = NetpDomainIdToSid(
|
|||
|
UserInfo->LogonDomainId,
|
|||
|
UserInfo->UserId,
|
|||
|
(PSID *) &Sids->Sids[0].SidPointer
|
|||
|
);
|
|||
|
|
|||
|
if( NetStatus != ERROR_SUCCESS ) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
Sids->Count++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Copy over all the groups passed as RIDs
|
|||
|
//
|
|||
|
|
|||
|
for ( i=0; i < UserInfo->GroupCount; i++ ) {
|
|||
|
|
|||
|
NetStatus = NetpDomainIdToSid(
|
|||
|
UserInfo->LogonDomainId,
|
|||
|
UserInfo->GroupIds[i].RelativeId,
|
|||
|
(PSID *) &Sids->Sids[Sids->Count].SidPointer
|
|||
|
);
|
|||
|
if( NetStatus != ERROR_SUCCESS ) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
Sids->Count++;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Add in the extra SIDs
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// ???: no need to allocate these
|
|||
|
//
|
|||
|
if (UserInfo->UserFlags & LOGON_EXTRA_SIDS) {
|
|||
|
|
|||
|
|
|||
|
for ( i = 0; i < UserInfo->SidCount; i++ ) {
|
|||
|
|
|||
|
|
|||
|
Sids->Sids[Sids->Count].SidPointer = NlpCopySid(
|
|||
|
UserInfo->ExtraSids[i].Sid
|
|||
|
);
|
|||
|
if (Sids->Sids[Sids->Count].SidPointer == NULL) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
Sids->Count++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Deallocate any memory we've allocated
|
|||
|
//
|
|||
|
|
|||
|
Cleanup:
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
if (Sids->Sids != NULL) {
|
|||
|
for (i = 0; i < Sids->Count ;i++ ) {
|
|||
|
if (Sids->Sids[i].SidPointer != NULL) {
|
|||
|
MIDL_user_free(Sids->Sids[i].SidPointer);
|
|||
|
}
|
|||
|
}
|
|||
|
MIDL_user_free(Sids->Sids);
|
|||
|
Sids->Sids = NULL;
|
|||
|
Sids->Count = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
return Status;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NlpAddResourceGroupsToSamInfo (
|
|||
|
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
|
|||
|
IN OUT PNETLOGON_VALIDATION_SAM_INFO4 *ValidationInformation,
|
|||
|
IN PSAMPR_PSID_ARRAY ResourceGroups
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function converts a NETLOGON_VALIDATION_SAM_INFO version 1, 2, or 4 to
|
|||
|
a NETLOGON_VALIDATION_SAM_INFO version 4 and optionally adds in an array of
|
|||
|
ResourceGroup sids.
|
|||
|
|
|||
|
Since version 4 is a superset of the other two levels, the returned structure can
|
|||
|
be used even though one of the other info levels are needed.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ValidationLevel -- Specifies the level of information passed as input in
|
|||
|
ValidationInformation. Must be NetlogonValidationSamInfo or
|
|||
|
NetlogonValidationSamInfo2, NetlogonValidationSamInfo4
|
|||
|
|
|||
|
NetlogonValidationSamInfo4 is always returned on output.
|
|||
|
|
|||
|
ValidationInformation -- Specifies the NETLOGON_VALIDATION_SAM_INFO
|
|||
|
to convert.
|
|||
|
|
|||
|
ResourceGroups - The list of resource groups to add to the structure.
|
|||
|
If NULL, no resource groups are added.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_INSUFFICIENT_RESOURCES: not enough memory to allocate the new
|
|||
|
structure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG Length;
|
|||
|
PNETLOGON_VALIDATION_SAM_INFO4 SamInfo = *ValidationInformation;
|
|||
|
PNETLOGON_VALIDATION_SAM_INFO4 SamInfo4;
|
|||
|
PBYTE Where;
|
|||
|
ULONG Index;
|
|||
|
ULONG GroupIndex;
|
|||
|
ULONG ExtraSids = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Calculate the size of the new structure
|
|||
|
//
|
|||
|
|
|||
|
Length = sizeof( NETLOGON_VALIDATION_SAM_INFO4 )
|
|||
|
+ SamInfo->GroupCount * sizeof(GROUP_MEMBERSHIP)
|
|||
|
+ RtlLengthSid( SamInfo->LogonDomainId );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Add space for extra sids & resource groups
|
|||
|
//
|
|||
|
|
|||
|
if ( ValidationLevel != NetlogonValidationSamInfo &&
|
|||
|
(SamInfo->UserFlags & LOGON_EXTRA_SIDS) != 0 ) {
|
|||
|
|
|||
|
for (Index = 0; Index < SamInfo->SidCount ; Index++ ) {
|
|||
|
Length += sizeof(NETLOGON_SID_AND_ATTRIBUTES) + RtlLengthSid(SamInfo->ExtraSids[Index].Sid);
|
|||
|
}
|
|||
|
ExtraSids += SamInfo->SidCount;
|
|||
|
}
|
|||
|
|
|||
|
if ( ResourceGroups != NULL ) {
|
|||
|
for (Index = 0; Index < ResourceGroups->Count ; Index++ ) {
|
|||
|
Length += sizeof(NETLOGON_SID_AND_ATTRIBUTES) + RtlLengthSid(ResourceGroups->Sids[Index].SidPointer);
|
|||
|
}
|
|||
|
ExtraSids += ResourceGroups->Count;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Round up now to take into account the round up in the
|
|||
|
// middle of marshalling
|
|||
|
//
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->LogonDomainName.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->LogonServer.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->EffectiveName.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->FullName.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->LogonScript.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->ProfilePath.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->HomeDirectory.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
if ( ValidationLevel == NetlogonValidationSamInfo4 ) {
|
|||
|
Length += SamInfo->DnsLogonDomainName.Length + sizeof(WCHAR)
|
|||
|
+ SamInfo->Upn.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
//
|
|||
|
// The ExpansionStrings may be used to transport byte aligned data
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString1.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString2.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString3.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString4.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString5.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString6.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString7.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString8.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString9.Length + sizeof(WCHAR);
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT(Length, sizeof(WCHAR))
|
|||
|
+ SamInfo->ExpansionString10.Length + sizeof(WCHAR);
|
|||
|
}
|
|||
|
|
|||
|
Length = ROUND_UP_COUNT( Length, sizeof(WCHAR) );
|
|||
|
|
|||
|
SamInfo4 = (PNETLOGON_VALIDATION_SAM_INFO4) MIDL_user_allocate( Length );
|
|||
|
|
|||
|
if ( !SamInfo4 ) {
|
|||
|
*ValidationInformation = NULL;
|
|||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// First copy the whole structure, since most parts are the same
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory( SamInfo4, SamInfo, sizeof(NETLOGON_VALIDATION_SAM_INFO));
|
|||
|
RtlZeroMemory( &((LPBYTE)SamInfo4)[sizeof(NETLOGON_VALIDATION_SAM_INFO)],
|
|||
|
sizeof(NETLOGON_VALIDATION_SAM_INFO4) - sizeof(NETLOGON_VALIDATION_SAM_INFO) );
|
|||
|
|
|||
|
//
|
|||
|
// Copy all the variable length data
|
|||
|
//
|
|||
|
|
|||
|
Where = (PBYTE) (SamInfo4 + 1);
|
|||
|
|
|||
|
RtlCopyMemory(
|
|||
|
Where,
|
|||
|
SamInfo->GroupIds,
|
|||
|
SamInfo->GroupCount * sizeof( GROUP_MEMBERSHIP) );
|
|||
|
|
|||
|
SamInfo4->GroupIds = (PGROUP_MEMBERSHIP) Where;
|
|||
|
Where += SamInfo->GroupCount * sizeof( GROUP_MEMBERSHIP );
|
|||
|
|
|||
|
//
|
|||
|
// Copy the extra groups
|
|||
|
//
|
|||
|
|
|||
|
if (ExtraSids != 0) {
|
|||
|
|
|||
|
ULONG SidLength;
|
|||
|
|
|||
|
SamInfo4->ExtraSids = (PNETLOGON_SID_AND_ATTRIBUTES) Where;
|
|||
|
Where += sizeof(NETLOGON_SID_AND_ATTRIBUTES) * ExtraSids;
|
|||
|
|
|||
|
GroupIndex = 0;
|
|||
|
|
|||
|
if ( ValidationLevel != NetlogonValidationSamInfo &&
|
|||
|
(SamInfo->UserFlags & LOGON_EXTRA_SIDS) != 0 ) {
|
|||
|
|
|||
|
for (Index = 0; Index < SamInfo->SidCount ; Index++ ) {
|
|||
|
|
|||
|
SamInfo4->ExtraSids[GroupIndex].Attributes = SamInfo->ExtraSids[Index].Attributes;
|
|||
|
SamInfo4->ExtraSids[GroupIndex].Sid = (PSID) Where;
|
|||
|
SidLength = RtlLengthSid(SamInfo->ExtraSids[Index].Sid);
|
|||
|
RtlCopyMemory(
|
|||
|
Where,
|
|||
|
SamInfo->ExtraSids[Index].Sid,
|
|||
|
SidLength
|
|||
|
|
|||
|
);
|
|||
|
Where += SidLength;
|
|||
|
GroupIndex++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Add the resource groups
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
if ( ResourceGroups != NULL ) {
|
|||
|
for (Index = 0; Index < ResourceGroups->Count ; Index++ ) {
|
|||
|
|
|||
|
SamInfo4->ExtraSids[GroupIndex].Attributes = SE_GROUP_MANDATORY |
|
|||
|
SE_GROUP_ENABLED |
|
|||
|
SE_GROUP_ENABLED_BY_DEFAULT;
|
|||
|
|
|||
|
SamInfo4->ExtraSids[GroupIndex].Sid = (PSID) Where;
|
|||
|
SidLength = RtlLengthSid(ResourceGroups->Sids[Index].SidPointer);
|
|||
|
RtlCopyMemory(
|
|||
|
Where,
|
|||
|
ResourceGroups->Sids[Index].SidPointer,
|
|||
|
SidLength
|
|||
|
);
|
|||
|
Where += SidLength;
|
|||
|
GroupIndex++;
|
|||
|
}
|
|||
|
}
|
|||
|
SamInfo4->SidCount = GroupIndex;
|
|||
|
NlAssert(GroupIndex == ExtraSids);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RtlCopyMemory(
|
|||
|
Where,
|
|||
|
SamInfo->LogonDomainId,
|
|||
|
RtlLengthSid( SamInfo->LogonDomainId ) );
|
|||
|
|
|||
|
SamInfo4->LogonDomainId = (PSID) Where;
|
|||
|
Where += RtlLengthSid( SamInfo->LogonDomainId );
|
|||
|
|
|||
|
//
|
|||
|
// Copy the WCHAR-aligned data
|
|||
|
//
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->EffectiveName,
|
|||
|
&SamInfo->EffectiveName,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->FullName,
|
|||
|
&SamInfo->FullName,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->LogonScript,
|
|||
|
&SamInfo->LogonScript,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ProfilePath,
|
|||
|
&SamInfo->ProfilePath,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->HomeDirectory,
|
|||
|
&SamInfo->HomeDirectory,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->HomeDirectoryDrive,
|
|||
|
&SamInfo->HomeDirectoryDrive,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->LogonServer,
|
|||
|
&SamInfo->LogonServer,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->LogonDomainName,
|
|||
|
&SamInfo->LogonDomainName,
|
|||
|
&Where );
|
|||
|
|
|||
|
if ( ValidationLevel == NetlogonValidationSamInfo4 ) {
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->DnsLogonDomainName,
|
|||
|
&SamInfo->DnsLogonDomainName,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->Upn,
|
|||
|
&SamInfo->Upn,
|
|||
|
&Where );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString1,
|
|||
|
&SamInfo->ExpansionString1,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString2,
|
|||
|
&SamInfo->ExpansionString2,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString3,
|
|||
|
&SamInfo->ExpansionString3,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString4,
|
|||
|
&SamInfo->ExpansionString4,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString5,
|
|||
|
&SamInfo->ExpansionString5,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString6,
|
|||
|
&SamInfo->ExpansionString6,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString7,
|
|||
|
&SamInfo->ExpansionString7,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString8,
|
|||
|
&SamInfo->ExpansionString8,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString9,
|
|||
|
&SamInfo->ExpansionString9,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
NlpPutString( &SamInfo4->ExpansionString10,
|
|||
|
&SamInfo->ExpansionString10,
|
|||
|
&Where );
|
|||
|
|
|||
|
Where = ROUND_UP_POINTER(Where, sizeof(WCHAR) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
MIDL_user_free(SamInfo);
|
|||
|
|
|||
|
*ValidationInformation = SamInfo4;
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NlpExpandResourceGroupMembership(
|
|||
|
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
|
|||
|
IN OUT PNETLOGON_VALIDATION_SAM_INFO4 * UserInfo,
|
|||
|
IN PDOMAIN_INFO DomainInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Given the validation information for a user, expands the group member-
|
|||
|
ships and user id into a list of sids
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ValidationLevel -- Specifies the level of information passed as input in
|
|||
|
UserInfo. Must be NetlogonValidationSamInfo or
|
|||
|
NetlogonValidationSamInfo2, NetlogonValidationSamInfo4
|
|||
|
|
|||
|
NetlogonValidationSamInfo4 is always returned on output.
|
|||
|
|
|||
|
UserInfo - user's validation information
|
|||
|
This structure is updated to include the resource groups that the user is a member of
|
|||
|
|
|||
|
DomainInfo - Structure identifying the hosted domain used to determine the group membership.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
|
|||
|
STATUS_INSUFFICIENT_RESOURCES - there wasn't enough memory to
|
|||
|
create the list of sids.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
SAMPR_PSID_ARRAY SidList = {0};
|
|||
|
PSAMPR_PSID_ARRAY ResourceGroups = NULL;
|
|||
|
ULONG Index;
|
|||
|
|
|||
|
|
|||
|
Status = NlpBuildPacSidList(
|
|||
|
*UserInfo,
|
|||
|
&SidList
|
|||
|
);
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
//
|
|||
|
// Call SAM to get the sids
|
|||
|
//
|
|||
|
|
|||
|
Status = SamIGetResourceGroupMembershipsTransitive(
|
|||
|
DomainInfo->DomSamAccountDomainHandle,
|
|||
|
&SidList,
|
|||
|
0, // no flags
|
|||
|
&ResourceGroups
|
|||
|
);
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Build a new validation information structure
|
|||
|
//
|
|||
|
|
|||
|
if (ResourceGroups->Count != 0) {
|
|||
|
|
|||
|
Status = NlpAddResourceGroupsToSamInfo(
|
|||
|
ValidationLevel,
|
|||
|
UserInfo,
|
|||
|
ResourceGroups
|
|||
|
);
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Cleanup:
|
|||
|
|
|||
|
SamIFreeSidArray(
|
|||
|
ResourceGroups
|
|||
|
);
|
|||
|
|
|||
|
if (SidList.Sids != NULL) {
|
|||
|
for (Index = 0; Index < SidList.Count ;Index++ ) {
|
|||
|
if (SidList.Sids[Index].SidPointer != NULL) {
|
|||
|
MIDL_user_free(SidList.Sids[Index].SidPointer);
|
|||
|
}
|
|||
|
}
|
|||
|
MIDL_user_free(SidList.Sids);
|
|||
|
}
|
|||
|
|
|||
|
return(Status);
|
|||
|
}
|