1605 lines
36 KiB
C
1605 lines
36 KiB
C
/*++
|
||
|
||
Copyright (c) 1987-1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
replutil.c
|
||
|
||
Abstract:
|
||
|
||
Low level functions for SSI Replication apis
|
||
|
||
Author:
|
||
|
||
Ported from Lan Man 2.0
|
||
|
||
Environment:
|
||
|
||
User mode only.
|
||
Contains NT-specific code.
|
||
Requires ANSI C extensions: slash-slash comments, long external names.
|
||
|
||
Revision History:
|
||
|
||
22-Jul-1991 (cliffv)
|
||
Ported to NT. Converted to NT style.
|
||
|
||
02-Jan-1992 (madana)
|
||
added support for builtin/multidomain replication.
|
||
|
||
04-Apr-1992 (madana)
|
||
Added support for LSA replication.
|
||
|
||
--*/
|
||
|
||
//
|
||
// Common include files.
|
||
//
|
||
|
||
#include "logonsrv.h" // Include files common to entire service
|
||
#pragma hdrstop
|
||
|
||
//
|
||
// Include files specific to this .c file
|
||
//
|
||
|
||
#include <accessp.h> // NetpConvertWorkstationList
|
||
#include "lsarepl.h"
|
||
|
||
|
||
|
||
DWORD
|
||
NlCopyUnicodeString (
|
||
IN PUNICODE_STRING InString,
|
||
OUT PUNICODE_STRING OutString
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine copies the input string to the output. It assumes that
|
||
the input string is allocated by MIDL_user_allocate() and sets the
|
||
input string buffer pointer to NULL so that the buffer will be not
|
||
freed on return.
|
||
|
||
Arguments:
|
||
|
||
InString - Points to the UNICODE string to copy.
|
||
|
||
OutString - Points to the UNICODE string which will be updated to point
|
||
to the input string.
|
||
|
||
Return Value:
|
||
|
||
Return the size of the MIDL buffer.
|
||
|
||
--*/
|
||
{
|
||
if ( InString->Length == 0 || InString->Buffer == NULL ) {
|
||
OutString->Length = 0;
|
||
OutString->MaximumLength = 0;
|
||
OutString->Buffer = NULL;
|
||
} else {
|
||
OutString->Length = InString->Length;
|
||
OutString->MaximumLength = InString->Length;
|
||
OutString->Buffer = InString->Buffer;
|
||
InString->Buffer = NULL;
|
||
}
|
||
|
||
return( OutString->MaximumLength );
|
||
}
|
||
|
||
|
||
DWORD
|
||
NlCopyData(
|
||
IN LPBYTE *InData,
|
||
OUT LPBYTE *OutData,
|
||
DWORD DataLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine copies the input data pointer to output data pointer.
|
||
It assumes that the input data buffer is allocated by the
|
||
MIDL_user_allocate() and sets the input buffer buffer pointer to
|
||
NULL on return so that the data buffer will not be freed by SamIFree
|
||
rountine.
|
||
|
||
Arguments:
|
||
|
||
InData - Points to input data buffer pointer.
|
||
|
||
OutString - Pointer to output data buffer pointer.
|
||
|
||
DataLength - Length of input data.
|
||
|
||
Return Value:
|
||
|
||
Return the size of the data copied.
|
||
|
||
--*/
|
||
{
|
||
*OutData = *InData;
|
||
*InData = NULL;
|
||
|
||
return(DataLength);
|
||
}
|
||
|
||
|
||
VOID
|
||
NlFreeDBDelta(
|
||
IN PNETLOGON_DELTA_ENUM Delta
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will free the midl buffers that are allocated for
|
||
a delta. This routine does nothing but call the midl generated free
|
||
routine.
|
||
|
||
Arguments:
|
||
|
||
Delta: pointer to the delta structure which has to be freed.
|
||
|
||
Return Value:
|
||
|
||
nothing
|
||
|
||
--*/
|
||
{
|
||
if( Delta != NULL ) {
|
||
_fgs__NETLOGON_DELTA_ENUM (Delta);
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
NlFreeDBDeltaArray(
|
||
IN PNETLOGON_DELTA_ENUM DeltaArray,
|
||
IN DWORD ArraySize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will free up all delta entries in enum array and the
|
||
array itself.
|
||
|
||
Arguments:
|
||
|
||
Delta: pointer to the delta structure array.
|
||
|
||
ArraySize: num of delta structures in the array.
|
||
|
||
Return Value:
|
||
|
||
nothing
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
|
||
if( DeltaArray != NULL ) {
|
||
|
||
for( i = 0; i < ArraySize; i++) {
|
||
NlFreeDBDelta( &DeltaArray[i] );
|
||
}
|
||
|
||
MIDL_user_free( DeltaArray );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamUser (
|
||
IN ULONG RelativeId,
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
IN LPDWORD BufferSize,
|
||
IN PSESSION_INFO SessionInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the specified user into the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
RelativeId - The relative Id of the user query.
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
SessionInfo: Info describing BDC that's calling us
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
SAMPR_HANDLE UserHandle = NULL;
|
||
PNETLOGON_DELTA_USER DeltaUser;
|
||
PSAMPR_USER_INFO_BUFFER UserAll = NULL;
|
||
|
||
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing User Object %lx\n", RelativeId));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = AddOrChangeUser;
|
||
Delta->DeltaID.Rid = RelativeId;
|
||
Delta->DeltaUnion.DeltaUser = NULL;
|
||
|
||
//
|
||
// Open a handle to the specified user.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamIOpenAccount( DBInfo->DBHandle,
|
||
RelativeId,
|
||
SecurityDbObjectSamUser,
|
||
&UserHandle );
|
||
STOPSAMTIMER;
|
||
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
UserHandle = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Query everything there is to know about this user.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationUser(
|
||
UserHandle,
|
||
UserInternal3Information,
|
||
&UserAll );
|
||
STOPSAMTIMER;
|
||
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
UserAll = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
NlPrint((NL_SYNC_MORE,
|
||
"\t User Object name %wZ\n",
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.UserName));
|
||
|
||
#define FIELDS_USED ( USER_ALL_USERNAME | \
|
||
USER_ALL_FULLNAME | \
|
||
USER_ALL_USERID | \
|
||
USER_ALL_PRIMARYGROUPID | \
|
||
USER_ALL_HOMEDIRECTORY | \
|
||
USER_ALL_HOMEDIRECTORYDRIVE | \
|
||
USER_ALL_SCRIPTPATH | \
|
||
USER_ALL_PROFILEPATH | \
|
||
USER_ALL_ADMINCOMMENT | \
|
||
USER_ALL_WORKSTATIONS | \
|
||
USER_ALL_LOGONHOURS | \
|
||
USER_ALL_LASTLOGON | \
|
||
USER_ALL_LASTLOGOFF | \
|
||
USER_ALL_BADPASSWORDCOUNT | \
|
||
USER_ALL_LOGONCOUNT | \
|
||
USER_ALL_PASSWORDLASTSET | \
|
||
USER_ALL_ACCOUNTEXPIRES | \
|
||
USER_ALL_USERACCOUNTCONTROL | \
|
||
USER_ALL_USERCOMMENT | \
|
||
USER_ALL_COUNTRYCODE | \
|
||
USER_ALL_CODEPAGE | \
|
||
USER_ALL_PARAMETERS | \
|
||
USER_ALL_NTPASSWORDPRESENT | \
|
||
USER_ALL_LMPASSWORDPRESENT | \
|
||
USER_ALL_PRIVATEDATA | \
|
||
USER_ALL_SECURITYDESCRIPTOR )
|
||
|
||
NlAssert( (UserAll->Internal3.I1.WhichFields & FIELDS_USED) == FIELDS_USED );
|
||
|
||
|
||
|
||
//
|
||
// Allocate a buffer to return to the caller.
|
||
//
|
||
|
||
DeltaUser = (PNETLOGON_DELTA_USER)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_USER) );
|
||
|
||
if (DeltaUser == NULL) {
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// wipe off the buffer so that cleanup will not be in fault.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaUser, sizeof(NETLOGON_DELTA_USER) );
|
||
// INIT_PLACE_HOLDER(DeltaUser);
|
||
|
||
Delta->DeltaUnion.DeltaUser = DeltaUser;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_USER);
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.UserName,
|
||
&DeltaUser->UserName );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.FullName,
|
||
&DeltaUser->FullName );
|
||
|
||
DeltaUser->UserId = UserAll->Internal3.I1.UserId;
|
||
DeltaUser->PrimaryGroupId = UserAll->Internal3.I1.PrimaryGroupId;
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.HomeDirectory,
|
||
&DeltaUser->HomeDirectory );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.HomeDirectoryDrive,
|
||
&DeltaUser->HomeDirectoryDrive );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.ScriptPath,
|
||
&DeltaUser->ScriptPath );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.AdminComment,
|
||
&DeltaUser->AdminComment );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.WorkStations,
|
||
&DeltaUser->WorkStations );
|
||
|
||
DeltaUser->LastLogon = UserAll->Internal3.I1.LastLogon;
|
||
DeltaUser->LastLogoff = UserAll->Internal3.I1.LastLogoff;
|
||
|
||
//
|
||
// Copy Logon Hours
|
||
//
|
||
|
||
DeltaUser->LogonHours.UnitsPerWeek = UserAll->Internal3.I1.LogonHours.UnitsPerWeek;
|
||
DeltaUser->LogonHours.LogonHours = UserAll->Internal3.I1.LogonHours.LogonHours;
|
||
UserAll->Internal3.I1.LogonHours.LogonHours = NULL; // Don't let SAM free this.
|
||
*BufferSize += (UserAll->Internal3.I1.LogonHours.UnitsPerWeek + 7) / 8;
|
||
|
||
|
||
|
||
DeltaUser->BadPasswordCount = UserAll->Internal3.I1.BadPasswordCount;
|
||
DeltaUser->LogonCount = UserAll->Internal3.I1.LogonCount;
|
||
|
||
DeltaUser->PasswordLastSet = UserAll->Internal3.I1.PasswordLastSet;
|
||
DeltaUser->AccountExpires = UserAll->Internal3.I1.AccountExpires;
|
||
|
||
//
|
||
// Don't copy lockout bit to BDC unless it understands it.
|
||
//
|
||
|
||
DeltaUser->UserAccountControl = UserAll->Internal3.I1.UserAccountControl;
|
||
if ( (SessionInfo->NegotiatedFlags & NETLOGON_SUPPORTS_ACCOUNT_LOCKOUT) == 0 ){
|
||
DeltaUser->UserAccountControl &= ~USER_ACCOUNT_AUTO_LOCKED;
|
||
}
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.UserComment,
|
||
&DeltaUser->UserComment );
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.Parameters,
|
||
&DeltaUser->Parameters );
|
||
|
||
DeltaUser->CountryCode = UserAll->Internal3.I1.CountryCode;
|
||
DeltaUser->CodePage = UserAll->Internal3.I1.CodePage;
|
||
|
||
//
|
||
// Set private data.
|
||
// Includes passwords and password history.
|
||
//
|
||
|
||
DeltaUser->PrivateData.SensitiveData = UserAll->Internal3.I1.PrivateDataSensitive;
|
||
|
||
if ( UserAll->Internal3.I1.PrivateDataSensitive ) {
|
||
|
||
CRYPT_BUFFER Data;
|
||
|
||
//
|
||
// encrypt private data using session key
|
||
// Re-use the SAM's buffer and encrypt it in place.
|
||
//
|
||
|
||
Data.Length = Data.MaximumLength = UserAll->Internal3.I1.PrivateData.Length;
|
||
Data.Buffer = (PUCHAR) UserAll->Internal3.I1.PrivateData.Buffer;
|
||
UserAll->Internal3.I1.PrivateData.Buffer = NULL;
|
||
|
||
Status = NlEncryptSensitiveData( &Data, SessionInfo );
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
DeltaUser->PrivateData.DataLength = Data.Length;
|
||
DeltaUser->PrivateData.Data = Data.Buffer;
|
||
} else {
|
||
|
||
DeltaUser->PrivateData.DataLength = UserAll->Internal3.I1.PrivateData.Length;
|
||
DeltaUser->PrivateData.Data = (PUCHAR) UserAll->Internal3.I1.PrivateData.Buffer;
|
||
|
||
UserAll->Internal3.I1.PrivateData.Buffer = NULL;
|
||
}
|
||
|
||
{ // ?? Macro requires a Local named SecurityDescriptor
|
||
PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor;
|
||
SecurityDescriptor = &UserAll->Internal3.I1.SecurityDescriptor;
|
||
DELTA_SECOBJ_INFO(DeltaUser);
|
||
}
|
||
|
||
|
||
//
|
||
// copy profile path in DummyStrings
|
||
//
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&UserAll->Internal3.I1.ProfilePath,
|
||
&DeltaUser->DummyString1 );
|
||
|
||
//
|
||
// Copy LastBadPasswordTime to DummyLong1 and DummyLong2.
|
||
//
|
||
|
||
DeltaUser->DummyLong1 = UserAll->Internal3.LastBadPasswordTime.HighPart;
|
||
DeltaUser->DummyLong2 = UserAll->Internal3.LastBadPasswordTime.LowPart;
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
|
||
Cleanup:
|
||
|
||
|
||
STARTSAMTIMER;
|
||
|
||
if( UserHandle != NULL ) {
|
||
(VOID) SamrCloseHandle( &UserHandle );
|
||
}
|
||
|
||
if ( UserAll != NULL ) {
|
||
SamIFree_SAMPR_USER_INFO_BUFFER( UserAll, UserInternal3Information );
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack USER object:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamGroup (
|
||
IN ULONG RelativeId,
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
LPDWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the specified group into the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
RelativeId - The relative Id of the group query.
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
SAMPR_HANDLE GroupHandle = NULL;
|
||
PNETLOGON_DELTA_GROUP DeltaGroup;
|
||
|
||
//
|
||
// Information returned from SAM
|
||
//
|
||
|
||
PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||
PSAMPR_GROUP_INFO_BUFFER GroupGeneral = NULL;
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing Group Object %lx\n", RelativeId ));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = AddOrChangeGroup;
|
||
Delta->DeltaID.Rid = RelativeId;
|
||
Delta->DeltaUnion.DeltaGroup = NULL;
|
||
|
||
//
|
||
// Open a handle to the specified group.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamIOpenAccount( DBInfo->DBHandle,
|
||
RelativeId,
|
||
SecurityDbObjectSamGroup,
|
||
&GroupHandle );
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
GroupHandle = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
QUERY_SAM_SECOBJ_INFO(GroupHandle);
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationGroup(
|
||
GroupHandle,
|
||
GroupReplicationInformation,
|
||
&GroupGeneral );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
GroupGeneral = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
NlPrint((NL_SYNC_MORE,
|
||
"\t Group Object name %wZ\n",
|
||
(PUNICODE_STRING)&GroupGeneral->General.Name ));
|
||
|
||
DeltaGroup = (PNETLOGON_DELTA_GROUP)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_GROUP) );
|
||
|
||
if( DeltaGroup == NULL ) {
|
||
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// wipe off the buffer so that cleanup will not be in fault.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaGroup, sizeof(NETLOGON_DELTA_GROUP) );
|
||
// INIT_PLACE_HOLDER(DeltaGroup);
|
||
|
||
Delta->DeltaUnion.DeltaGroup = DeltaGroup;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_GROUP);
|
||
|
||
*BufferSize = NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&GroupGeneral->General.Name,
|
||
&DeltaGroup->Name );
|
||
|
||
DeltaGroup->RelativeId = RelativeId;
|
||
DeltaGroup->Attributes = GroupGeneral->General.Attributes;
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&GroupGeneral->General.AdminComment,
|
||
&DeltaGroup->AdminComment );
|
||
|
||
|
||
DELTA_SECOBJ_INFO(DeltaGroup);
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
Cleanup:
|
||
STARTSAMTIMER;
|
||
|
||
if( GroupHandle != NULL ) {
|
||
(VOID) SamrCloseHandle( &GroupHandle );
|
||
}
|
||
|
||
if ( SecurityDescriptor != NULL ) {
|
||
SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
|
||
}
|
||
|
||
if ( GroupGeneral != NULL ) {
|
||
SamIFree_SAMPR_GROUP_INFO_BUFFER( GroupGeneral,
|
||
GroupReplicationInformation );
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack GROUP object:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamGroupMember (
|
||
IN ULONG RelativeId,
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
LPDWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the membership of the specified group into
|
||
the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
RelativeId - The relative Id of the group query.
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
SAMPR_HANDLE GroupHandle = NULL;
|
||
DWORD Size;
|
||
PNETLOGON_DELTA_GROUP_MEMBER DeltaGroupMember;
|
||
|
||
//
|
||
// Information returned from SAM
|
||
//
|
||
|
||
PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL;
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing GroupMember Object %lx\n", RelativeId));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = ChangeGroupMembership;
|
||
Delta->DeltaID.Rid = RelativeId;
|
||
Delta->DeltaUnion.DeltaGroupMember = NULL;
|
||
|
||
//
|
||
// Open a handle to the specified group.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamIOpenAccount( DBInfo->DBHandle,
|
||
RelativeId,
|
||
SecurityDbObjectSamGroup,
|
||
&GroupHandle );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
GroupHandle = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Find out everything there is to know about the group.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrGetMembersInGroup( GroupHandle, &MembersBuffer );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
MembersBuffer = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
DeltaGroupMember = (PNETLOGON_DELTA_GROUP_MEMBER)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_GROUP_MEMBER) );
|
||
|
||
if( DeltaGroupMember == NULL ) {
|
||
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// wipe off the buffer so that cleanup will not be in fault.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaGroupMember,
|
||
sizeof(NETLOGON_DELTA_GROUP_MEMBER) );
|
||
|
||
Delta->DeltaUnion.DeltaGroupMember = DeltaGroupMember;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_GROUP_MEMBER);
|
||
|
||
if ( MembersBuffer->MemberCount != 0 ) {
|
||
Size = MembersBuffer->MemberCount * sizeof(*MembersBuffer->Members);
|
||
|
||
*BufferSize += NlCopyData(
|
||
(LPBYTE *)&MembersBuffer->Members,
|
||
(LPBYTE *)&DeltaGroupMember->MemberIds,
|
||
Size );
|
||
|
||
Size = MembersBuffer->MemberCount *
|
||
sizeof(*MembersBuffer->Attributes);
|
||
|
||
*BufferSize += NlCopyData(
|
||
(LPBYTE *)&MembersBuffer->Attributes,
|
||
(LPBYTE *)&DeltaGroupMember->Attributes,
|
||
Size );
|
||
}
|
||
|
||
DeltaGroupMember->MemberCount = MembersBuffer->MemberCount;
|
||
|
||
//
|
||
// Initialize placeholder strings to NULL.
|
||
//
|
||
|
||
DeltaGroupMember->DummyLong1 = 0;
|
||
DeltaGroupMember->DummyLong2 = 0;
|
||
DeltaGroupMember->DummyLong3 = 0;
|
||
DeltaGroupMember->DummyLong4 = 0;
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
Cleanup:
|
||
STARTSAMTIMER;
|
||
|
||
if( GroupHandle != NULL ) {
|
||
(VOID) SamrCloseHandle( &GroupHandle );
|
||
}
|
||
|
||
if ( MembersBuffer != NULL ) {
|
||
SamIFree_SAMPR_GET_MEMBERS_BUFFER( MembersBuffer );
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack GROUPMEMBER object:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamAlias (
|
||
IN ULONG RelativeId,
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
LPDWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the specified alias into the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
RelativeId - The relative Id of the alias query.
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
SAMPR_HANDLE AliasHandle = NULL;
|
||
PNETLOGON_DELTA_ALIAS DeltaAlias;
|
||
|
||
//
|
||
// Information returned from SAM
|
||
//
|
||
|
||
PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||
|
||
PSAMPR_ALIAS_INFO_BUFFER AliasGeneral = NULL;
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing Alias Object %lx\n", RelativeId));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = AddOrChangeAlias;
|
||
Delta->DeltaID.Rid = RelativeId;
|
||
Delta->DeltaUnion.DeltaAlias = NULL;
|
||
|
||
//
|
||
// Open a handle to the specified alias.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamIOpenAccount( DBInfo->DBHandle,
|
||
RelativeId,
|
||
SecurityDbObjectSamAlias,
|
||
&AliasHandle );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
AliasHandle = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
QUERY_SAM_SECOBJ_INFO(AliasHandle);
|
||
|
||
//
|
||
// Determine the alias name.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationAlias(
|
||
AliasHandle,
|
||
AliasReplicationInformation,
|
||
&AliasGeneral );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
AliasGeneral = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
NlPrint((NL_SYNC_MORE, "\t Alias Object name %wZ\n",
|
||
(PUNICODE_STRING)&(AliasGeneral->General.Name)));
|
||
|
||
DeltaAlias = (PNETLOGON_DELTA_ALIAS)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_ALIAS) );
|
||
|
||
if( DeltaAlias == NULL ) {
|
||
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// wipe off the buffer so that cleanup will not be in fault.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaAlias, sizeof(NETLOGON_DELTA_ALIAS) );
|
||
// INIT_PLACE_HOLDER(DeltaAlias);
|
||
|
||
Delta->DeltaUnion.DeltaAlias = DeltaAlias;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_ALIAS);
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&(AliasGeneral->General.Name),
|
||
&DeltaAlias->Name );
|
||
|
||
DeltaAlias->RelativeId = RelativeId;
|
||
|
||
DELTA_SECOBJ_INFO(DeltaAlias);
|
||
|
||
//
|
||
// copy comment string
|
||
//
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&(AliasGeneral->General.AdminComment),
|
||
&DeltaAlias->DummyString1 );
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
Cleanup:
|
||
STARTSAMTIMER;
|
||
|
||
if( AliasHandle != NULL ) {
|
||
(VOID) SamrCloseHandle( &AliasHandle );
|
||
}
|
||
|
||
if ( SecurityDescriptor != NULL ) {
|
||
SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
|
||
}
|
||
|
||
|
||
if( AliasGeneral != NULL ) {
|
||
|
||
SamIFree_SAMPR_ALIAS_INFO_BUFFER (
|
||
AliasGeneral,
|
||
AliasReplicationInformation );
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack ALIAS object:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamAliasMember (
|
||
IN ULONG RelativeId,
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
LPDWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the membership of the specified alias into
|
||
the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
RelativeId - The relative Id of the alias query.
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
SAMPR_HANDLE AliasHandle = NULL;
|
||
PNETLOGON_DELTA_ALIAS_MEMBER DeltaAliasMember;
|
||
DWORD i;
|
||
|
||
//
|
||
// Information returned from SAM
|
||
//
|
||
|
||
NLPR_SID_ARRAY Members;
|
||
PNLPR_SID_INFORMATION Sids;
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing AliasMember Object %lx\n", RelativeId));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = ChangeAliasMembership;
|
||
Delta->DeltaID.Rid = RelativeId;
|
||
Delta->DeltaUnion.DeltaAliasMember = NULL;
|
||
|
||
Members.Sids = NULL;
|
||
|
||
|
||
//
|
||
// Open a handle to the specified alias.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamIOpenAccount( DBInfo->DBHandle,
|
||
RelativeId,
|
||
SecurityDbObjectSamAlias,
|
||
&AliasHandle );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
AliasHandle = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Find out everything there is to know about the alias.
|
||
//
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrGetMembersInAlias( AliasHandle,
|
||
(PSAMPR_PSID_ARRAY)&Members );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
Members.Sids = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
DeltaAliasMember = (PNETLOGON_DELTA_ALIAS_MEMBER)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_ALIAS_MEMBER) );
|
||
|
||
if( DeltaAliasMember == NULL ) {
|
||
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// wipe off the buffer so that cleanup will not be in fault.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaAliasMember,
|
||
sizeof(NETLOGON_DELTA_ALIAS_MEMBER) );
|
||
|
||
Delta->DeltaUnion.DeltaAliasMember = DeltaAliasMember;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_ALIAS_MEMBER);
|
||
|
||
//
|
||
// tie up sam return node to our return node
|
||
//
|
||
|
||
DeltaAliasMember->Members = Members;
|
||
|
||
//
|
||
// however, compute the MIDL buffer consumed for members node.
|
||
//
|
||
|
||
for(i = 0, Sids = Members.Sids; i < Members.Count; ++i, Sids++) {
|
||
|
||
*BufferSize += (sizeof(PNLPR_SID_INFORMATION) +
|
||
RtlLengthSid(Sids->SidPointer));
|
||
|
||
}
|
||
|
||
*BufferSize += sizeof(SAMPR_PSID_ARRAY);
|
||
|
||
//
|
||
// Initialize placeholder strings to NULL.
|
||
//
|
||
|
||
DeltaAliasMember->DummyLong1 = 0;
|
||
DeltaAliasMember->DummyLong2 = 0;
|
||
DeltaAliasMember->DummyLong3 = 0;
|
||
DeltaAliasMember->DummyLong4 = 0;
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
Cleanup:
|
||
|
||
STARTSAMTIMER;
|
||
|
||
if( AliasHandle != NULL ) {
|
||
(VOID) SamrCloseHandle( &AliasHandle );
|
||
}
|
||
|
||
if ( Members.Sids != NULL ) {
|
||
|
||
//
|
||
// don't free this node because we have tied up this
|
||
// node to our return info to RPC which will free it up
|
||
// when it is done with it.
|
||
//
|
||
// however, free this node under error conditions
|
||
//
|
||
|
||
}
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
|
||
SamIFree_SAMPR_PSID_ARRAY( (PSAMPR_PSID_ARRAY)&Members );
|
||
|
||
if( Delta->DeltaUnion.DeltaAliasMember != NULL ) {
|
||
Delta->DeltaUnion.DeltaAliasMember->Members.Sids = NULL;
|
||
}
|
||
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Timing for ALIASMEBER object packing:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlPackSamDomain (
|
||
IN OUT PNETLOGON_DELTA_ENUM Delta,
|
||
IN PDB_INFO DBInfo,
|
||
IN LPDWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pack a description of the sam domain into the specified buffer.
|
||
|
||
Arguments:
|
||
|
||
Delta: pointer to the delta structure where the new delta will
|
||
be returned.
|
||
|
||
DBInfo: pointer to the database info structure.
|
||
|
||
BufferSize: size of MIDL buffer that is consumed for this delta is
|
||
returned here.
|
||
|
||
Return Value:
|
||
|
||
NT status code.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
|
||
PNETLOGON_DELTA_DOMAIN DeltaDomain = NULL;
|
||
|
||
//
|
||
// Information returned from SAM
|
||
//
|
||
|
||
PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||
PSAMPR_DOMAIN_INFO_BUFFER DomainGeneral = NULL;
|
||
PSAMPR_DOMAIN_INFO_BUFFER DomainPassword = NULL;
|
||
PSAMPR_DOMAIN_INFO_BUFFER DomainModified = NULL;
|
||
PSAMPR_DOMAIN_INFO_BUFFER DomainLockout = NULL;
|
||
|
||
DEFPACKTIMER;
|
||
DEFSAMTIMER;
|
||
|
||
INITPACKTIMER;
|
||
INITSAMTIMER;
|
||
|
||
STARTPACKTIMER;
|
||
|
||
NlPrint((NL_SYNC_MORE, "Packing Domain Object\n"));
|
||
|
||
*BufferSize = 0;
|
||
|
||
Delta->DeltaType = AddOrChangeDomain;
|
||
Delta->DeltaID.Rid = 0;
|
||
Delta->DeltaUnion.DeltaDomain = NULL;
|
||
|
||
|
||
QUERY_SAM_SECOBJ_INFO(DBInfo->DBHandle);
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationDomain(
|
||
DBInfo->DBHandle,
|
||
DomainGeneralInformation,
|
||
&DomainGeneral );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DomainGeneral = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationDomain(
|
||
DBInfo->DBHandle,
|
||
DomainPasswordInformation,
|
||
&DomainPassword );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DomainPassword = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationDomain(
|
||
DBInfo->DBHandle,
|
||
DomainModifiedInformation,
|
||
&DomainModified );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DomainModified = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
STARTSAMTIMER;
|
||
|
||
Status = SamrQueryInformationDomain(
|
||
DBInfo->DBHandle,
|
||
DomainLockoutInformation,
|
||
&DomainLockout );
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DomainLockout = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Fill in the delta structure
|
||
//
|
||
|
||
|
||
DeltaDomain = (PNETLOGON_DELTA_DOMAIN)
|
||
MIDL_user_allocate( sizeof(NETLOGON_DELTA_DOMAIN) );
|
||
|
||
if( DeltaDomain == NULL ) {
|
||
|
||
Status = STATUS_NO_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Zero the buffer so that cleanup will not access violate.
|
||
//
|
||
|
||
RtlZeroMemory( DeltaDomain, sizeof(NETLOGON_DELTA_DOMAIN) );
|
||
// INIT_PLACE_HOLDER(DeltaDomain);
|
||
|
||
Delta->DeltaUnion.DeltaDomain = DeltaDomain;
|
||
*BufferSize += sizeof(NETLOGON_DELTA_DOMAIN);
|
||
|
||
*BufferSize += NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&DomainGeneral->General.DomainName,
|
||
&DeltaDomain->DomainName );
|
||
|
||
*BufferSize = NlCopyUnicodeString(
|
||
(PUNICODE_STRING)&DomainGeneral->General.OemInformation,
|
||
&DeltaDomain->OemInformation );
|
||
|
||
DeltaDomain->ForceLogoff = DomainGeneral->General.ForceLogoff;
|
||
DeltaDomain->MinPasswordLength =
|
||
DomainPassword->Password.MinPasswordLength;
|
||
DeltaDomain->PasswordHistoryLength =
|
||
DomainPassword->Password.PasswordHistoryLength;
|
||
|
||
NEW_TO_OLD_LARGE_INTEGER(
|
||
DomainPassword->Password.MaxPasswordAge,
|
||
DeltaDomain->MaxPasswordAge );
|
||
|
||
NEW_TO_OLD_LARGE_INTEGER(
|
||
DomainPassword->Password.MinPasswordAge,
|
||
DeltaDomain->MinPasswordAge );
|
||
|
||
NEW_TO_OLD_LARGE_INTEGER(
|
||
DomainModified->Modified.DomainModifiedCount,
|
||
DeltaDomain->DomainModifiedCount );
|
||
|
||
NEW_TO_OLD_LARGE_INTEGER(
|
||
DomainModified->Modified.CreationTime,
|
||
DeltaDomain->DomainCreationTime );
|
||
|
||
|
||
DELTA_SECOBJ_INFO(DeltaDomain);
|
||
|
||
//
|
||
// replicate PasswordProperties using reserved field.
|
||
//
|
||
|
||
DeltaDomain->DummyLong1 =
|
||
DomainPassword->Password.PasswordProperties;
|
||
|
||
//
|
||
// Replicate DOMAIN_LOCKOUT_INFORMATION using reserved field.
|
||
//
|
||
|
||
DeltaDomain->DummyString1.Buffer = (LPWSTR) DomainLockout;
|
||
DeltaDomain->DummyString1.MaximumLength =
|
||
DeltaDomain->DummyString1.Length = sizeof( DomainLockout->Lockout);
|
||
DomainLockout = NULL;
|
||
|
||
//
|
||
// All Done
|
||
//
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
Cleanup:
|
||
|
||
STARTSAMTIMER;
|
||
|
||
if ( SecurityDescriptor != NULL ) {
|
||
SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
|
||
}
|
||
|
||
if ( DomainGeneral != NULL ) {
|
||
SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainGeneral,
|
||
DomainGeneralInformation );
|
||
}
|
||
|
||
if ( DomainPassword != NULL ) {
|
||
SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainPassword,
|
||
DomainPasswordInformation );
|
||
}
|
||
|
||
if ( DomainModified != NULL ) {
|
||
SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainModified,
|
||
DomainModifiedInformation );
|
||
}
|
||
|
||
if ( DomainLockout != NULL ) {
|
||
SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainLockout,
|
||
DomainLockoutInformation );
|
||
}
|
||
|
||
STOPSAMTIMER;
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NlFreeDBDelta( Delta );
|
||
*BufferSize = 0;
|
||
}
|
||
|
||
STOPPACKTIMER;
|
||
|
||
NlPrint((NL_REPL_OBJ_TIME,"Timing for DOMAIN object packing:\n"));
|
||
PRINTPACKTIMER;
|
||
PRINTSAMTIMER;
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
NlEncryptSensitiveData(
|
||
IN OUT PCRYPT_BUFFER Data,
|
||
IN PSESSION_INFO SessionInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Encrypt data using the the server session key.
|
||
|
||
Either DES or RC4 will be used depending on the negotiated flags in SessionInfo.
|
||
|
||
Arguments:
|
||
|
||
Data: Pointer to the data to be decrypted. If the decrypted data is longer
|
||
than the encrypt data, this routine will allocate a buffer for
|
||
the returned data using MIDL_user_allocate and return a description to
|
||
that buffer here. In that case, this routine will free the buffer
|
||
containing the encrypted text data using MIDL_user_free.
|
||
|
||
SessionInfo: Info describing BDC that's calling us
|
||
|
||
Return Value:
|
||
|
||
NT status code
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
DATA_KEY KeyData;
|
||
|
||
|
||
//
|
||
// If both sides support RC4 encryption, use it.
|
||
//
|
||
|
||
if ( SessionInfo->NegotiatedFlags & NETLOGON_SUPPORTS_RC4_ENCRYPTION ) {
|
||
|
||
NlEncryptRC4( Data->Buffer, Data->Length, SessionInfo );
|
||
Status = STATUS_SUCCESS;
|
||
|
||
|
||
//
|
||
// If the other side is running NT 3.1,
|
||
// use the slower DES based encryption.
|
||
//
|
||
|
||
} else {
|
||
CYPHER_DATA TempData;
|
||
|
||
//
|
||
// Build a data buffer to describe the encryption key.
|
||
//
|
||
|
||
KeyData.Length = sizeof(NETLOGON_SESSION_KEY);
|
||
KeyData.MaximumLength = sizeof(NETLOGON_SESSION_KEY);
|
||
KeyData.Buffer = (PVOID)&SessionInfo->SessionKey;
|
||
|
||
//
|
||
// Build a data buffer to describe the encrypted data.
|
||
//
|
||
|
||
TempData.Length = 0;
|
||
TempData.MaximumLength = 0;
|
||
TempData.Buffer = NULL;
|
||
|
||
//
|
||
// First time make the encrypt call to determine the length.
|
||
//
|
||
|
||
Status = RtlEncryptData(
|
||
(PCLEAR_DATA)Data,
|
||
&KeyData,
|
||
&TempData );
|
||
|
||
if( Status != STATUS_BUFFER_TOO_SMALL ) {
|
||
return(Status);
|
||
}
|
||
|
||
//
|
||
// allocate output buffer.
|
||
//
|
||
|
||
TempData.MaximumLength = TempData.Length;
|
||
TempData.Buffer = MIDL_user_allocate( TempData.Length );
|
||
|
||
if( TempData.Buffer == NULL ) {
|
||
return(STATUS_NO_MEMORY);
|
||
}
|
||
|
||
//
|
||
// Encrypt the data.
|
||
//
|
||
|
||
IF_NL_DEBUG( ENCRYPT ) {
|
||
NlPrint((NL_ENCRYPT, "NlEncryptSensitiveData: Clear data: " ));
|
||
NlpDumpBuffer( NL_ENCRYPT, Data->Buffer, Data->Length );
|
||
}
|
||
|
||
Status = RtlEncryptData(
|
||
(PCLEAR_DATA)Data,
|
||
&KeyData,
|
||
&TempData );
|
||
|
||
IF_NL_DEBUG( ENCRYPT ) {
|
||
NlPrint((NL_ENCRYPT, "NlEncryptSensitiveData: Encrypted data: " ));
|
||
NlpDumpBuffer( NL_ENCRYPT, TempData.Buffer, TempData.Length );
|
||
}
|
||
|
||
//
|
||
// Return either the clear text or encrypted buffer to the caller.
|
||
//
|
||
|
||
if( NT_SUCCESS(Status) ) {
|
||
MIDL_user_free( Data->Buffer );
|
||
Data->Length = TempData.Length;
|
||
Data->MaximumLength = TempData.MaximumLength;
|
||
Data->Buffer = TempData.Buffer;
|
||
} else {
|
||
MIDL_user_free( TempData.Buffer );
|
||
}
|
||
|
||
}
|
||
|
||
return( Status );
|
||
|
||
}
|
||
|