mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1959 lines
48 KiB
1959 lines
48 KiB
/*++
|
|
|
|
Copyright (c) 1987-1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
nlrepl.c
|
|
|
|
Abstract:
|
|
|
|
The database replication functions called either from LSA OR SAM.
|
|
The actual code resides in netlogon.dll.
|
|
|
|
Author:
|
|
|
|
Madan Appiah (Madana)
|
|
|
|
Environment:
|
|
|
|
User mode only.
|
|
Contains NT-specific code.
|
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|
|
|
Revision History:
|
|
|
|
14-Apr-1992 (madana)
|
|
Created.
|
|
|
|
--*/
|
|
|
|
#include <nt.h> // needed for NTSTATUS
|
|
#include <ntrtl.h> // needed for nturtl.h
|
|
#include <nturtl.h> // needed for windows.h
|
|
#include <windows.h> // win32 typedefs
|
|
|
|
#include <crypt.h> // samsrv.h will need this
|
|
#include <ntlsa.h> // needed for POLICY_LSA_SERVER_ROLE
|
|
#include <samrpc.h>
|
|
#include <samisrv.h> // needed for SECURITY_DB_TYPE etc.
|
|
#include <winsock2.h> // needed for SOCKET defn's
|
|
#include <nlrepl.h> // proto types
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyDelta) (
|
|
IN SECURITY_DB_TYPE DbType,
|
|
IN LARGE_INTEGER ModificationCount,
|
|
IN SECURITY_DB_DELTA_TYPE DeltaType,
|
|
IN SECURITY_DB_OBJECT_TYPE ObjectType,
|
|
IN ULONG ObjectRid,
|
|
IN PSID ObjectSid,
|
|
IN PUNICODE_STRING ObjectName,
|
|
IN DWORD ReplicationImmediately,
|
|
IN PSAM_DELTA_DATA MemberId
|
|
);
|
|
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyRole) (
|
|
IN POLICY_LSA_SERVER_ROLE Role
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyMachineAccount) (
|
|
IN ULONG ObjectRid,
|
|
IN PSID DomainSid,
|
|
IN ULONG OldUserAccountControl,
|
|
IN ULONG NewUserAccountControl,
|
|
IN PUNICODE_STRING ObjectName
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyTrustedDomain) (
|
|
IN PSID HostedDomainSid,
|
|
IN PSID TrustedDomainSid,
|
|
IN BOOLEAN IsDeletion
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyNetlogonDllHandle) (
|
|
IN PHANDLE Role
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonSetServiceBits)(
|
|
IN DWORD ServiceBitsOfInterest,
|
|
IN DWORD ServiceBits
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonGetSerialNumber) (
|
|
IN SECURITY_DB_TYPE DbType,
|
|
IN PSID DomainSid,
|
|
OUT PLARGE_INTEGER SerialNumber
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonLdapLookup)(
|
|
IN PVOID Filter,
|
|
OUT PVOID *Response,
|
|
OUT PULONG ResponseSize
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonLdapLookupEx)(
|
|
IN PVOID Filter,
|
|
IN PVOID SockAddr,
|
|
OUT PVOID *Response,
|
|
OUT PULONG ResponseSize
|
|
);
|
|
|
|
typedef VOID
|
|
(*PI_NetLogonFree)(
|
|
IN PVOID Buffer
|
|
);
|
|
|
|
typedef NET_API_STATUS
|
|
(*PI_DsGetDcCache)(
|
|
IN LPCWSTR NetbiosDomainName OPTIONAL,
|
|
IN LPCWSTR DnsDomainName OPTIONAL,
|
|
OUT PBOOLEAN InNt4Domain,
|
|
OUT LPDWORD InNt4DomainTime
|
|
);
|
|
|
|
typedef NET_API_STATUS
|
|
(*PDsrGetDcName)(
|
|
IN LPWSTR ComputerName OPTIONAL,
|
|
IN LPWSTR DomainName OPTIONAL,
|
|
IN GUID *DomainGuid OPTIONAL,
|
|
IN GUID *SiteGuid OPTIONAL,
|
|
IN ULONG Flags,
|
|
OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
|
|
);
|
|
|
|
typedef NET_API_STATUS
|
|
(*PDsrGetDcNameEx2)(
|
|
IN LPWSTR ComputerName OPTIONAL,
|
|
IN LPCWSTR AccountName OPTIONAL,
|
|
IN ULONG AllowableAccountControlBits,
|
|
IN LPWSTR DomainName OPTIONAL,
|
|
IN GUID *DomainGuid OPTIONAL,
|
|
IN LPWSTR SiteName OPTIONAL,
|
|
IN ULONG Flags,
|
|
OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyDsChange)(
|
|
IN NL_DS_CHANGE_TYPE DsChangeType
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonReadChangeLog)(
|
|
IN PVOID InContext,
|
|
IN ULONG InContextSize,
|
|
IN ULONG ChangeBufferSize,
|
|
OUT PVOID *ChangeBuffer,
|
|
OUT PULONG BytesRead,
|
|
OUT PVOID *OutContext,
|
|
OUT PULONG OutContextSize
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonNewChangeLog)(
|
|
OUT HANDLE *ChangeLogHandle
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonAppendChangeLog)(
|
|
IN HANDLE ChangeLogHandle,
|
|
IN PVOID ChangeBuffer,
|
|
IN ULONG ChangeBufferSize
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonCloseChangeLog)(
|
|
IN HANDLE ChangeLogHandle,
|
|
IN BOOLEAN Commit
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonSendToSamOnPdc)(
|
|
IN LPWSTR DomainName,
|
|
IN LPBYTE OpaqueBuffer,
|
|
IN ULONG OpaqueBufferSize
|
|
);
|
|
|
|
typedef NET_API_STATUS
|
|
(*PI_NetLogonGetIpAddresses)(
|
|
OUT PULONG IpAddressCount,
|
|
OUT LPBYTE *IpAddresses
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonGetAuthDataEx)(
|
|
IN LPWSTR HostedDomainName,
|
|
IN LPWSTR TrustedDomainName,
|
|
IN BOOLEAN ResetChannel,
|
|
IN ULONG Flags,
|
|
OUT LPWSTR *ServerName,
|
|
OUT PNL_OS_VERSION ServerOsVersion,
|
|
OUT LPWSTR *ServerPrincipleName,
|
|
OUT PVOID *ClientContext,
|
|
OUT PULONG AuthnLevel
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetLogonGetDirectDomain)(
|
|
IN LPWSTR HostedDomainName,
|
|
IN LPWSTR TrustedDomainName,
|
|
OUT LPWSTR *DirectDomainName
|
|
);
|
|
|
|
typedef NTSTATUS
|
|
(*PI_NetNotifyNtdsDsaDeletion) (
|
|
IN LPWSTR DnsDomainName,
|
|
IN GUID *DomainGuid,
|
|
IN GUID *DsaGuid,
|
|
IN LPWSTR DnsHostName
|
|
);
|
|
|
|
typedef NET_API_STATUS
|
|
(*PI_NetLogonAddressToSiteName)(
|
|
IN PSOCKET_ADDRESS SocketAddress,
|
|
OUT LPWSTR *SiteName
|
|
);
|
|
|
|
//
|
|
// Global status
|
|
//
|
|
|
|
HANDLE NetlogonDllHandle = NULL;
|
|
PI_NetNotifyDelta pI_NetNotifyDelta = NULL;
|
|
PI_NetNotifyRole pI_NetNotifyRole = NULL;
|
|
PI_NetNotifyMachineAccount pI_NetNotifyMachineAccount = NULL;
|
|
PI_NetNotifyTrustedDomain pI_NetNotifyTrustedDomain = NULL;
|
|
PI_NetLogonSetServiceBits pI_NetLogonSetServiceBits = NULL;
|
|
PI_NetLogonGetSerialNumber pI_NetLogonGetSerialNumber = NULL;
|
|
PI_NetLogonLdapLookup pI_NetLogonLdapLookup = NULL;
|
|
PI_NetLogonLdapLookupEx pI_NetLogonLdapLookupEx = NULL;
|
|
PI_NetLogonFree pI_NetLogonFree = NULL;
|
|
PI_DsGetDcCache pI_DsGetDcCache = NULL;
|
|
PDsrGetDcName pDsrGetDcName = NULL;
|
|
PDsrGetDcNameEx2 pDsrGetDcNameEx2 = NULL;
|
|
PI_NetNotifyDsChange pI_NetNotifyDsChange = NULL;
|
|
PI_NetLogonReadChangeLog pI_NetLogonReadChangeLog = NULL;
|
|
PI_NetLogonNewChangeLog pI_NetLogonNewChangeLog = NULL;
|
|
PI_NetLogonAppendChangeLog pI_NetLogonAppendChangeLog = NULL;
|
|
PI_NetLogonCloseChangeLog pI_NetLogonCloseChangeLog = NULL;
|
|
PI_NetLogonSendToSamOnPdc pI_NetLogonSendToSamOnPdc = NULL;
|
|
PI_NetLogonGetIpAddresses pI_NetLogonGetIpAddresses = NULL;
|
|
PI_NetLogonGetAuthDataEx pI_NetLogonGetAuthDataEx = NULL;
|
|
PI_NetLogonGetDirectDomain pI_NetLogonGetDirectDomain = NULL;
|
|
PI_NetNotifyNtdsDsaDeletion pI_NetNotifyNtdsDsaDeletion = NULL;
|
|
PI_NetLogonAddressToSiteName pI_NetLogonAddressToSiteName = NULL;
|
|
|
|
|
|
NTSTATUS
|
|
NlLoadNetlogonDll(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function loads the netlogon.dll module if it is not loaded
|
|
already. If the network is not installed then netlogon.dll will not
|
|
present in the system and the LoadLibrary will fail.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
NT Status code.
|
|
|
|
--*/
|
|
{
|
|
static NTSTATUS DllLoadStatus = STATUS_SUCCESS;
|
|
PI_NetNotifyNetlogonDllHandle pI_NetNotifyNetlogonDllHandle = NULL;
|
|
HANDLE DllHandle = NULL;
|
|
|
|
|
|
//
|
|
// If we've tried to load the DLL before and it failed,
|
|
// return the same error code again.
|
|
//
|
|
|
|
if( DllLoadStatus != STATUS_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// Load netlogon.dll
|
|
//
|
|
|
|
DllHandle = LoadLibraryA( "Netlogon" );
|
|
|
|
if ( DllHandle == NULL ) {
|
|
|
|
#if DBG
|
|
DWORD DbgError;
|
|
|
|
DbgError = GetLastError();
|
|
|
|
DbgPrint("[Security Process] can't load netlogon.dll %d \n",
|
|
DbgError);
|
|
#endif // DBG
|
|
|
|
DllLoadStatus = STATUS_DLL_NOT_FOUND;
|
|
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Macro to grab the address of the named procedure from netlogon.dll
|
|
//
|
|
|
|
#if DBG
|
|
#define GRAB_ADDRESS( _X ) \
|
|
p##_X = (P##_X) GetProcAddress( DllHandle, #_X ); \
|
|
\
|
|
if ( p##_X == NULL ) { \
|
|
DbgPrint("[security process] can't load " #_X " procedure. %ld\n", GetLastError()); \
|
|
DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND;\
|
|
goto Cleanup; \
|
|
}
|
|
|
|
#else // DBG
|
|
#define GRAB_ADDRESS( _X ) \
|
|
p##_X = (P##_X) GetProcAddress( DllHandle, #_X ); \
|
|
\
|
|
if ( p##_X == NULL ) { \
|
|
DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND;\
|
|
goto Cleanup; \
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
|
|
//
|
|
// Get the addresses of the required procedures.
|
|
//
|
|
|
|
GRAB_ADDRESS( I_NetNotifyDelta );
|
|
GRAB_ADDRESS( I_NetNotifyRole );
|
|
GRAB_ADDRESS( I_NetNotifyMachineAccount );
|
|
GRAB_ADDRESS( I_NetNotifyTrustedDomain );
|
|
GRAB_ADDRESS( I_NetLogonSetServiceBits );
|
|
GRAB_ADDRESS( I_NetLogonGetSerialNumber );
|
|
GRAB_ADDRESS( I_NetLogonLdapLookup );
|
|
GRAB_ADDRESS( I_NetLogonLdapLookupEx );
|
|
GRAB_ADDRESS( I_NetLogonFree );
|
|
GRAB_ADDRESS( I_DsGetDcCache );
|
|
GRAB_ADDRESS( DsrGetDcName );
|
|
GRAB_ADDRESS( DsrGetDcNameEx2 );
|
|
GRAB_ADDRESS( I_NetNotifyDsChange );
|
|
GRAB_ADDRESS( I_NetLogonReadChangeLog );
|
|
GRAB_ADDRESS( I_NetLogonNewChangeLog );
|
|
GRAB_ADDRESS( I_NetLogonAppendChangeLog );
|
|
GRAB_ADDRESS( I_NetLogonCloseChangeLog );
|
|
GRAB_ADDRESS( I_NetLogonSendToSamOnPdc );
|
|
GRAB_ADDRESS( I_NetLogonGetIpAddresses );
|
|
GRAB_ADDRESS( I_NetLogonGetAuthDataEx );
|
|
GRAB_ADDRESS( I_NetLogonGetDirectDomain );
|
|
GRAB_ADDRESS( I_NetNotifyNtdsDsaDeletion );
|
|
GRAB_ADDRESS( I_NetLogonAddressToSiteName );
|
|
|
|
//
|
|
// Find the address of the I_NetNotifyNetlogonDllHandle procedure.
|
|
// This is an optional procedure so don't complain if it isn't there.
|
|
//
|
|
|
|
pI_NetNotifyNetlogonDllHandle = (PI_NetNotifyNetlogonDllHandle)
|
|
GetProcAddress( DllHandle, "I_NetNotifyNetlogonDllHandle" );
|
|
|
|
|
|
|
|
DllLoadStatus = STATUS_SUCCESS;
|
|
|
|
Cleanup:
|
|
if (DllLoadStatus == STATUS_SUCCESS) {
|
|
NetlogonDllHandle = DllHandle;
|
|
|
|
//
|
|
// Notify Netlogon that we've loaded it.
|
|
//
|
|
|
|
if( pI_NetNotifyNetlogonDllHandle != NULL ) {
|
|
(VOID) (*pI_NetNotifyNetlogonDllHandle)( &NetlogonDllHandle );
|
|
}
|
|
|
|
} else {
|
|
if ( DllHandle != NULL ) {
|
|
FreeLibrary( DllHandle );
|
|
}
|
|
}
|
|
return( DllLoadStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyDelta (
|
|
IN SECURITY_DB_TYPE DbType,
|
|
IN LARGE_INTEGER ModificationCount,
|
|
IN SECURITY_DB_DELTA_TYPE DeltaType,
|
|
IN SECURITY_DB_OBJECT_TYPE ObjectType,
|
|
IN ULONG ObjectRid,
|
|
IN PSID ObjectSid,
|
|
IN PUNICODE_STRING ObjectName,
|
|
IN DWORD ReplicationImmediately,
|
|
IN PSAM_DELTA_DATA MemberId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the SAM and LSA services after each
|
|
change is made to the SAM and LSA databases. The services describe
|
|
the type of object that is modified, the type of modification made
|
|
on the object, the serial number of this modification etc. This
|
|
information is stored for later retrieval when a BDC or member
|
|
server wants a copy of this change. See the description of
|
|
I_NetSamDeltas for a description of how the change log is used.
|
|
|
|
Add a change log entry to circular change log maintained in cache as
|
|
well as on the disk and update the head and tail pointers
|
|
|
|
It is assumed that Tail points to a block where this new change log
|
|
entry may be stored.
|
|
|
|
NOTE: The actual code is in netlogon.dll. This wrapper function
|
|
will determine whether the network is installed, if so, it calls the
|
|
actual worker function after loading the netlogon.dll module. If the
|
|
network is not installed then this will function will return with
|
|
appropriate error code.
|
|
|
|
Arguments:
|
|
|
|
DbType - Type of the database that has been modified.
|
|
|
|
ModificationCount - The value of the DomainModifiedCount field for the
|
|
domain following the modification.
|
|
|
|
DeltaType - The type of modification that has been made on the object.
|
|
|
|
ObjectType - The type of object that has been modified.
|
|
|
|
ObjectRid - The relative ID of the object that has been modified.
|
|
This parameter is valid only when the object type specified is
|
|
either SecurityDbObjectSamUser, SecurityDbObjectSamGroup or
|
|
SecurityDbObjectSamAlias otherwise this parameter is set to zero.
|
|
|
|
ObjectSid - The SID of the object that has been modified. If the object
|
|
modified is in a SAM database, ObjectSid is the DomainId of the Domain
|
|
containing the object.
|
|
|
|
ObjectName - The name of the secret object when the object type
|
|
specified is SecurityDbObjectLsaSecret or the old name of the object
|
|
when the object type specified is either SecurityDbObjectSamUser,
|
|
SecurityDbObjectSamGroup or SecurityDbObjectSamAlias and the delta
|
|
type is SecurityDbRename otherwise this parameter is set to NULL.
|
|
|
|
ReplicateImmediately - TRUE if the change should be immediately
|
|
replicated to all BDCs. A password change should set the flag
|
|
TRUE.
|
|
|
|
MemberId - This parameter is specified when group/alias membership
|
|
is modified. This structure will then point to the member's ID that
|
|
has been updated.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The Service completed successfully.
|
|
|
|
--*/
|
|
{
|
|
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyDelta)(
|
|
DbType,
|
|
ModificationCount,
|
|
DeltaType,
|
|
ObjectType,
|
|
ObjectRid,
|
|
ObjectSid,
|
|
ObjectName,
|
|
ReplicationImmediately,
|
|
MemberId
|
|
);
|
|
|
|
return( STATUS_SUCCESS );
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyRole(
|
|
IN POLICY_LSA_SERVER_ROLE Role
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the LSA service upon LSA initialization
|
|
and when LSA changes domain role. This routine will initialize the
|
|
change log cache if the role specified is PDC or delete the change
|
|
log cache if the role specified is other than PDC.
|
|
|
|
When this function initializing the change log if the change log
|
|
currently exists on disk, the cache will be initialized from disk.
|
|
LSA should treat errors from this routine as non-fatal. LSA should
|
|
log the errors so they may be corrected then continue
|
|
initialization. However, LSA should treat the system databases as
|
|
read-only in this case.
|
|
|
|
NOTE: The actual code is in netlogon.dll. This wrapper function
|
|
will determine whether the network is installed, if so, it calls the
|
|
actual worker function after loading the netlogon.dll module. If the
|
|
network is not installed then this will function will return with
|
|
appropriate error code.
|
|
|
|
Arguments:
|
|
|
|
Role - Current role of the server.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The Service completed successfully.
|
|
|
|
--*/
|
|
{
|
|
|
|
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyRole)(
|
|
Role
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetNotifyRole returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( STATUS_SUCCESS );
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyMachineAccount (
|
|
IN ULONG ObjectRid,
|
|
IN PSID DomainSid,
|
|
IN ULONG OldUserAccountControl,
|
|
IN ULONG NewUserAccountControl,
|
|
IN PUNICODE_STRING ObjectName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the SAM to indicate that the account type
|
|
of a machine account has changed. Specifically, if
|
|
USER_INTERDOMAIN_TRUST_ACCOUNT, USER_WORKSTATION_TRUST_ACCOUNT, or
|
|
USER_SERVER_TRUST_ACCOUNT change for a particular account, this
|
|
routine is called to let Netlogon know of the account change.
|
|
|
|
NOTE: The actual code is in netlogon.dll. This wrapper function
|
|
will determine whether the network is installed, if so, it calls the
|
|
actual worker function after loading the netlogon.dll module. If the
|
|
network is not installed then this will function will return with
|
|
appropriate error code.
|
|
|
|
Arguments:
|
|
|
|
ObjectRid - The relative ID of the object that has been modified.
|
|
|
|
DomainSid - Specifies the SID of the Domain containing the object.
|
|
|
|
OldUserAccountControl - Specifies the previous value of the
|
|
UserAccountControl field of the user.
|
|
|
|
NewUserAccountControl - Specifies the new (current) value of the
|
|
UserAccountControl field of the user.
|
|
|
|
ObjectName - The name of the account being changed.
|
|
|
|
Return Value:
|
|
|
|
Status of the operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyMachineAccount)(
|
|
ObjectRid,
|
|
DomainSid,
|
|
OldUserAccountControl,
|
|
NewUserAccountControl,
|
|
ObjectName );
|
|
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetNotifyMachineAccount returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyTrustedDomain (
|
|
IN PSID HostedDomainSid,
|
|
IN PSID TrustedDomainSid,
|
|
IN BOOLEAN IsDeletion
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the LSA to indicate that a trusted domain
|
|
object has changed.
|
|
|
|
This function is called for both PDC and BDC.
|
|
|
|
Arguments:
|
|
|
|
HostedDomainSid - Domain SID of the domain the trust is from.
|
|
|
|
TrustedDomainSid - Domain SID of the domain the trust is to.
|
|
|
|
IsDeletion - TRUE if the trusted domain object was deleted.
|
|
FALSE if the trusted domain object was created or modified.
|
|
|
|
|
|
Return Value:
|
|
|
|
Status of the operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyTrustedDomain)(
|
|
HostedDomainSid,
|
|
TrustedDomainSid,
|
|
IsDeletion );
|
|
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetNotifyTrustedDomain returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonSetServiceBits(
|
|
IN DWORD ServiceBitsOfInterest,
|
|
IN DWORD ServiceBits
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Inidcates whether this DC is currently running the specified service.
|
|
|
|
For instance,
|
|
|
|
I_NetLogonSetServiceBits( DS_KDC_FLAG, DS_KDC_FLAG );
|
|
|
|
tells Netlogon the KDC is running. And
|
|
|
|
I_NetLogonSetServiceBits( DS_KDC_FLAG, 0 );
|
|
|
|
tells Netlogon the KDC is not running.
|
|
|
|
Arguments:
|
|
|
|
ServiceBitsOfInterest - A mask of the service bits being changed, set,
|
|
or reset by this call. Only the following flags are valid:
|
|
|
|
DS_KDC_FLAG
|
|
DS_DS_FLAG
|
|
DS_TIMESERV_FLAG
|
|
|
|
ServiceBits - A mask indicating what the bits specified by ServiceBitsOfInterest
|
|
should be set to.
|
|
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Success.
|
|
|
|
STATUS_INVALID_PARAMETER - The parameters have extaneous bits set.
|
|
|
|
STATUS_DLL_NOT_FOUND - Netlogon.dll could not be loaded.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonSetServiceBits)(
|
|
ServiceBitsOfInterest,
|
|
ServiceBits );
|
|
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonSetServiceBits returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonGetSerialNumber (
|
|
IN SECURITY_DB_TYPE DbType,
|
|
IN PSID DomainSid,
|
|
OUT PLARGE_INTEGER SerialNumber
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the SAM and LSA services when they startup
|
|
to get the current serial number written to the changelog.
|
|
|
|
Arguments:
|
|
|
|
DbType - Type of the database that has been modified.
|
|
|
|
DomainSid - For the SAM and builtin database, this specifies the DomainId of
|
|
the domain whose serial number is to be returned.
|
|
|
|
SerialNumber - Returns the latest set value of the DomainModifiedCount
|
|
field for the domain.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The Service completed successfully.
|
|
|
|
STATUS_INVALID_DOMAIN_ROLE - This machine is not the PDC.
|
|
|
|
STATUS_DLL_NOT_FOUND - Netlogon.dll could not be loaded.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonGetSerialNumber)(
|
|
DbType,
|
|
DomainSid,
|
|
SerialNumber );
|
|
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonGetSerialNumber returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
I_NetLogonLdapLookup(
|
|
IN PVOID Filter,
|
|
OUT PVOID *Response,
|
|
OUT PULONG ResponseSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine builds a response to an LDAP ping of a DC. DsGetDcName does
|
|
such a ping to ensure the DC is functional and still meets the requirements
|
|
of the DsGetDcName. DsGetDcName does an LDAP lookup of the NULL DN asking
|
|
for attribute "Netlogon". The DS turns that into a call to this routine
|
|
passing in the filter parameter.
|
|
|
|
Arguments:
|
|
|
|
Filter - Filter describing the query. The filter is built by the DsGetDcName
|
|
client, so we can limit the flexibility significantly. The filter is:
|
|
|
|
Response - Returns a pointer to an allocated buffer containing
|
|
the response to return to the caller. This response is a binary blob
|
|
which should be returned to the caller bit-for-bit intact.
|
|
The buffer should be freed be calling I_NetLogonFree.
|
|
|
|
ResponseSize - Size (in bytes) of the returned message.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS -- The response was returned in the supplied buffer.
|
|
|
|
STATUS_INVALID_PARAMETER -- The filter was invalid.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonLdapLookup)(
|
|
Filter,
|
|
Response,
|
|
ResponseSize );
|
|
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonLdapLookup returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
|
|
}
|
|
|
|
NTSTATUS
|
|
I_NetLogonLdapLookupEx(
|
|
IN PVOID Filter,
|
|
IN PVOID SockAddr,
|
|
OUT PVOID *Response,
|
|
OUT PULONG ResponseSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine builds a response to an LDAP ping of a DC. DsGetDcName does
|
|
such a ping to ensure the DC is functional and still meets the requirements
|
|
of the DsGetDcName. DsGetDcName does an LDAP lookup of the NULL DN asking
|
|
for attribute "Netlogon". The DS turns that into a call to this routine
|
|
passing in the filter parameter.
|
|
|
|
Arguments:
|
|
|
|
Filter - Filter describing the query. The filter is built by the DsGetDcName
|
|
client, so we can limit the flexibility significantly. The filter is:
|
|
|
|
SockAddr - Address of the client that sent the ping.
|
|
|
|
Response - Returns a pointer to an allocated buffer containing
|
|
the response to return to the caller. This response is a binary blob
|
|
which should be returned to the caller bit-for-bit intact.
|
|
The buffer should be freed be calling I_NetLogonFree.
|
|
|
|
ResponseSize - Size (in bytes) of the returned message.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS -- The response was returned in the supplied buffer.
|
|
|
|
STATUS_INVALID_PARAMETER -- The filter was invalid.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonLdapLookupEx)(
|
|
Filter,
|
|
SockAddr,
|
|
Response,
|
|
ResponseSize );
|
|
|
|
#ifdef notdef // Failures occur frequently in nature
|
|
#if DBG
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonLdapLookupEx returns 0x%lx\n",
|
|
NtStatus);
|
|
}
|
|
#endif // DBG
|
|
#endif // notdef
|
|
|
|
return( NtStatus );
|
|
|
|
}
|
|
|
|
VOID
|
|
I_NetLogonFree(
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Free any buffer allocated by Netlogon and returned to an in-process caller.
|
|
|
|
Arguments:
|
|
|
|
Buffer - Buffer to deallocate.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
(*pI_NetLogonFree)( Buffer );
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
I_DsGetDcCache(
|
|
IN LPCWSTR NetbiosDomainName OPTIONAL,
|
|
IN LPCWSTR DnsDomainName OPTIONAL,
|
|
OUT PBOOLEAN InNt4Domain,
|
|
OUT LPDWORD InNt4DomainTime
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine finds a domain entry that matches the caller's query.
|
|
|
|
Arguments:
|
|
|
|
NetbiosDomainName - Specifies the Netbios name of the domain to find.
|
|
|
|
DnsDomainName - Specifies the Dns name of the domain to find.
|
|
|
|
At least one of the above parameters should be non-NULL.
|
|
|
|
InNt4Domain - Returns true if the domain is an NT 4.0 domain.
|
|
|
|
InNt4DomainTime - Returns the GetTickCount time of when the domain was
|
|
detected to be an NT 4.0 domain.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR: Information is returned about the domain.
|
|
|
|
ERROR_NO_SUCH_DOMAIN: cached information is not available for this domain.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
NET_API_STATUS NetStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NetStatus = (*pI_DsGetDcCache)(
|
|
NetbiosDomainName,
|
|
DnsDomainName,
|
|
InNt4Domain,
|
|
InNt4DomainTime );
|
|
|
|
return( NetStatus );
|
|
}
|
|
|
|
NET_API_STATUS
|
|
DsrGetDcName(
|
|
IN LPWSTR ComputerName OPTIONAL,
|
|
IN LPWSTR DomainName OPTIONAL,
|
|
IN GUID *DomainGuid OPTIONAL,
|
|
IN GUID *SiteGuid OPTIONAL,
|
|
IN ULONG Flags,
|
|
OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Same as DsGetDcNameW except:
|
|
|
|
* This is the RPC server side implementation.
|
|
|
|
Arguments:
|
|
|
|
Same as DsGetDcNameW except as above.
|
|
|
|
Return Value:
|
|
|
|
Same as DsGetDcNameW except as above.
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
NET_API_STATUS NetStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NetStatus = (*pDsrGetDcName)(
|
|
ComputerName,
|
|
DomainName,
|
|
DomainGuid,
|
|
SiteGuid,
|
|
Flags,
|
|
DomainControllerInfo );
|
|
|
|
return( NetStatus );
|
|
}
|
|
|
|
NET_API_STATUS
|
|
DsrGetDcNameEx2(
|
|
IN LPWSTR ComputerName OPTIONAL,
|
|
IN LPWSTR AccountName OPTIONAL,
|
|
IN ULONG AllowableAccountControlBits,
|
|
IN LPWSTR DomainName OPTIONAL,
|
|
IN GUID *DomainGuid OPTIONAL,
|
|
IN LPWSTR SiteName OPTIONAL,
|
|
IN ULONG Flags,
|
|
OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Same as DsGetDcNameW except:
|
|
|
|
AccountName - Account name to pass on the ping request.
|
|
If NULL, no account name will be sent.
|
|
|
|
AllowableAccountControlBits - Mask of allowable account types for AccountName.
|
|
|
|
* This is the RPC server side implementation.
|
|
|
|
Arguments:
|
|
|
|
Same as DsGetDcNameW except as above.
|
|
|
|
Return Value:
|
|
|
|
Same as DsGetDcNameW except as above.
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
NET_API_STATUS NetStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NetStatus = (*pDsrGetDcNameEx2)(
|
|
ComputerName,
|
|
AccountName,
|
|
AllowableAccountControlBits,
|
|
DomainName,
|
|
DomainGuid,
|
|
SiteName,
|
|
Flags,
|
|
DomainControllerInfo );
|
|
|
|
return( NetStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyDsChange(
|
|
IN NL_DS_CHANGE_TYPE DsChangeType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the LSA to indicate that configuration information
|
|
in the DS has changed.
|
|
|
|
This function is called for both PDC and BDC.
|
|
|
|
Arguments:
|
|
|
|
DsChangeType - Indicates the type of information that has changed.
|
|
|
|
Return Value:
|
|
|
|
Status of the operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyDsChange)(
|
|
DsChangeType
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetNotifyDsChange &ld returns 0x%lx \n",
|
|
DsChangeType,
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonReadChangeLog(
|
|
IN PVOID InContext,
|
|
IN ULONG InContextSize,
|
|
IN ULONG ChangeBufferSize,
|
|
OUT PVOID *ChangeBuffer,
|
|
OUT PULONG BytesRead,
|
|
OUT PVOID *OutContext,
|
|
OUT PULONG OutContextSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns a portion of the change log to the caller.
|
|
|
|
The caller asks for the first portion of the change log by passing zero as
|
|
the InContext/InContextSize. Each call passes out an OutContext that
|
|
identifies the last change returned to the caller. That context can
|
|
be passed in on a subsequent call to I_NetlogonReadChangeLog.
|
|
|
|
Arguments:
|
|
|
|
InContext - Opaque context describing the last entry to have been previously
|
|
returned. Specify NULL to request the first entry.
|
|
|
|
InContextSize - Size (in bytes) of InContext. Specify 0 to request the
|
|
first entry.
|
|
|
|
ChangeBufferSize - Specifies the size (in bytes) of the passed in ChangeBuffer.
|
|
|
|
ChangeBuffer - Returns the next several entries from the change log.
|
|
Buffer must be DWORD aligned.
|
|
|
|
BytesRead - Returns the size (in bytes) of the entries returned in ChangeBuffer.
|
|
|
|
OutContext - Returns an opaque context describing the last entry returned
|
|
in ChangeBuffer. NULL is returned if no entries were returned.
|
|
The buffer must be freed using I_NetLogonFree
|
|
|
|
OutContextSize - Returns the size (in bytes) of OutContext.
|
|
|
|
|
|
Return Value:
|
|
|
|
STATUS_MORE_ENTRIES - More entries are available. This function should
|
|
be called again to retrieve the remaining entries.
|
|
|
|
STATUS_SUCCESS - No more entries are currently available. Some entries may
|
|
have been returned on this call. This function need not be called again.
|
|
However, the caller can determine if new change log entries were
|
|
added to the log, by calling this function again passing in the returned
|
|
context.
|
|
|
|
STATUS_INVALID_PARAMETER - InContext is invalid.
|
|
Either it is too short or the change log entry described no longer
|
|
exists in the change log.
|
|
|
|
STATUS_INVALID_DOMAIN_ROLE - Change log not initialized
|
|
|
|
STATUS_NO_MEMORY - There is not enough memory to allocate OutContext.
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonReadChangeLog)(
|
|
InContext,
|
|
InContextSize,
|
|
ChangeBufferSize,
|
|
ChangeBuffer,
|
|
BytesRead,
|
|
OutContext,
|
|
OutContextSize
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonReadChangeLog returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonNewChangeLog(
|
|
OUT HANDLE *ChangeLogHandle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function opens a new changelog file for writing. The new changelog
|
|
is a temporary file. The real change log will not be modified until
|
|
I_NetLogonCloseChangeLog is called asking to Commit the changes.
|
|
|
|
The caller should follow this call by Zero more calls to
|
|
I_NetLogonAppendChangeLog followed by a call to I_NetLogonCloseChangeLog.
|
|
|
|
Only one temporary change log can be active at once.
|
|
|
|
Arguments:
|
|
|
|
ChangeLogHandle - Returns a handle identifying the temporary change log.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The temporary change log has been successfully opened.
|
|
|
|
STATUS_INVALID_DOMAIN_ROLE - DC is neither PDC nor BDC.
|
|
|
|
STATUS_NO_MEMORY - Not enough memory to create the change log buffer.
|
|
|
|
Sundry file creation errors.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonNewChangeLog)(
|
|
ChangeLogHandle
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonNewChangeLog returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonAppendChangeLog(
|
|
IN HANDLE ChangeLogHandle,
|
|
IN PVOID ChangeBuffer,
|
|
IN ULONG ChangeBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function appends change log information to new changelog file.
|
|
|
|
The ChangeBuffer must be a change buffer returned from I_NetLogonReadChangeLog.
|
|
Care should be taken to ensure each call to I_NetLogonReadChangeLog is
|
|
exactly matched by one call to I_NetLogonAppendChangeLog.
|
|
|
|
Arguments:
|
|
|
|
ChangeLogHandle - A handle identifying the temporary change log.
|
|
|
|
ChangeBuffer - A buffer describing a set of changes returned from
|
|
I_NetLogonReadChangeLog.
|
|
|
|
ChangeBufferSize - Size (in bytes) of ChangeBuffer.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The temporary change log has been successfully opened.
|
|
|
|
STATUS_INVALID_DOMAIN_ROLE - DC is neither PDC nor BDC.
|
|
|
|
STATUS_INVALID_HANDLE - ChangeLogHandle is not valid.
|
|
|
|
STATUS_INVALID_PARAMETER - ChangeBuffer contains invalid data.
|
|
|
|
Sundry disk write errors.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonAppendChangeLog)(
|
|
ChangeLogHandle,
|
|
ChangeBuffer,
|
|
ChangeBufferSize
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonAppendChangeLog returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonCloseChangeLog(
|
|
IN HANDLE ChangeLogHandle,
|
|
IN BOOLEAN Commit
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function closes a new changelog file.
|
|
|
|
Arguments:
|
|
|
|
ChangeLogHandle - A handle identifying the temporary change log.
|
|
|
|
Commit - If true, the specified changes are written to the primary change log.
|
|
If false, the specified change are deleted.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The temporary change log has been successfully opened.
|
|
|
|
STATUS_INVALID_DOMAIN_ROLE - DC is neither PDC nor BDC.
|
|
|
|
STATUS_INVALID_HANDLE - ChangeLogHandle is not valid.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonCloseChangeLog)(
|
|
ChangeLogHandle,
|
|
Commit
|
|
);
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonCloseChangeLog returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonSendToSamOnPdc(
|
|
IN LPWSTR DomainName,
|
|
IN LPBYTE OpaqueBuffer,
|
|
IN ULONG OpaqueBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sends an opaque buffer from SAM on a BDC to SAM on the PDC of
|
|
the specified domain.
|
|
|
|
The original use of this routine will be to allow the BDC to forward user
|
|
account password changes to the PDC.
|
|
|
|
|
|
Arguments:
|
|
|
|
DomainName - Identifies the hosted domain that this request applies to.
|
|
DomainName may be the Netbios domain name or the DNS domain name.
|
|
NULL implies the primary domain hosted by this DC.
|
|
|
|
OpaqueBuffer - Buffer to be passed to the SAM service on the PDC.
|
|
The buffer will be encrypted on the wire.
|
|
|
|
OpaqueBufferSize - Size (in bytes) of OpaqueBuffer.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS: Message successfully sent to PDC
|
|
|
|
STATUS_NO_MEMORY: There is not enough memory to complete the operation
|
|
|
|
STATUS_NO_SUCH_DOMAIN: DomainName does not correspond to a hosted domain
|
|
|
|
STATUS_NO_LOGON_SERVERS: PDC is not currently available
|
|
|
|
STATUS_NOT_SUPPORTED: PDC does not support this operation
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonSendToSamOnPdc)(
|
|
DomainName,
|
|
OpaqueBuffer,
|
|
OpaqueBufferSize );
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonSendToSamOnPdc returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
NET_API_STATUS
|
|
I_NetLogonGetIpAddresses(
|
|
OUT PULONG IpAddressCount,
|
|
OUT LPBYTE *IpAddresses
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns all of the IP Addresses assigned to this machine.
|
|
|
|
Arguments:
|
|
|
|
|
|
IpAddressCount - Returns the number of IP addresses assigned to this machine.
|
|
|
|
IpAddresses - Returns a buffer containing an array of SOCKET_ADDRESS
|
|
structures.
|
|
This buffer should be freed using I_NetLogonFree().
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR - Success
|
|
|
|
ERROR_NOT_ENOUGH_MEMORY - There was not enough memory to complete the operation.
|
|
|
|
ERROR_NETLOGON_NOT_STARTED - Netlogon is not started.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
NET_API_STATUS NetStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NetStatus = (*pI_NetLogonGetIpAddresses)(
|
|
IpAddressCount,
|
|
IpAddresses );
|
|
|
|
return( NetStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonGetAuthDataEx(
|
|
IN LPWSTR HostedDomainName,
|
|
IN LPWSTR TrustedDomainName,
|
|
IN BOOLEAN ResetChannel,
|
|
IN ULONG Flags,
|
|
OUT LPWSTR *ServerName,
|
|
OUT PNL_OS_VERSION ServerOsVersion,
|
|
OUT LPWSTR *ServerPrincipleName,
|
|
OUT PVOID *ClientContext,
|
|
OUT PULONG AuthnLevel
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the data that a caller could passed to
|
|
RpcBindingSetAuthInfoW to do an RPC call using the Netlogon security package.
|
|
|
|
The returned data is valid for the life of Netlogon's secure channel to
|
|
the current DC. There is no way for the caller to determine that lifetime.
|
|
So, the caller should be prepared for access to be denied and respond to that
|
|
by calling I_NetLogonGetAuthData again.
|
|
|
|
Once the returned data is passed to RpcBindingSetAuthInfoW, the data should
|
|
not be deallocated until after the binding handle is closed.
|
|
|
|
Arguments:
|
|
|
|
HostedDomainName - Identifies the hosted domain that this request applies to.
|
|
DomainName may be the Netbios domain name or the DNS domain name.
|
|
NULL implies the primary domain hosted by this machine.
|
|
|
|
TrustedDomainName - Identifies the domain the trust relationship is to.
|
|
DomainName may be the Netbios domain name or the DNS domain name.
|
|
|
|
ResetChannel - If true, specifies that the netlogon secure channel
|
|
is to be reset.
|
|
|
|
Flags - Flags defining which ClientContext to return:
|
|
|
|
NL_DIRECT_TRUST_REQUIRED: Indicates that STATUS_NO_SUCH_DOMAIN should be returned
|
|
if TrustedDomainName is not directly trusted.
|
|
|
|
NL_RETURN_CLOSEST_HOP: Indicates that for indirect trust, the "closest hop"
|
|
session should be returned rather than the actual session
|
|
|
|
NL_ROLE_PRIMARY_OK: Indicates that if this is a PDC, it's OK to return
|
|
the client session to the primary domain.
|
|
|
|
NL_REQUIRE_DOMAIN_IN_FOREST - Indicates that STATUS_NO_SUCH_DOMAIN should be returned
|
|
if TrustedDomainName is not a domain in the forest.
|
|
|
|
ServerName - UNC name of a DC in the trusted domain.
|
|
The caller should RPC to the named DC. This DC is the only DC
|
|
that has the server side context associated with the ClientContext
|
|
given below.
|
|
The buffer must be freed using I_NetLogonFree.
|
|
|
|
ServerOsVersion - Returns the operating system version of the machine named ServerName
|
|
|
|
ServerPrincipleName - ServerPrincipleName to pass to RpcBindingSetAutInfo.
|
|
(See note above about when this data can be deallocated.)
|
|
The buffer must be freed using I_NetLogonFree.
|
|
|
|
ClientContext - Authentication data to pass as AuthIdentity to RpcBindingSetAutInfo.
|
|
(See note above about when this data can be deallocated.)
|
|
The buffer must be freed using I_NetLogonFree.
|
|
|
|
|
|
AuthnLevel - Authentication level Netlogon will use for its secure
|
|
channel. This value will be one of:
|
|
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY: Sign and seal
|
|
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: Sign only
|
|
|
|
The caller can ignore this value and independently choose an authentication
|
|
level.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS: The auth data was successfully returned.
|
|
|
|
STATUS_NO_MEMORY: There is not enough memory to complete the operation
|
|
|
|
STATUS_NETLOGON_NOT_STARTED: Netlogon is not running
|
|
|
|
STATUS_NO_SUCH_DOMAIN: HostedDomainName does not correspond to a hosted domain, OR
|
|
TrustedDomainName is not a trusted domain.
|
|
|
|
STATUS_NO_LOGON_SERVERS: No DCs are not currently available
|
|
|
|
STATUS_NOT_SUPPORTED: DC does not support this operation
|
|
Probably because the DC in the trusted domain is running NT 4.0,
|
|
or Netlogon on this machine is configured to neither sign nor seal.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonGetAuthDataEx)(
|
|
HostedDomainName,
|
|
TrustedDomainName,
|
|
ResetChannel,
|
|
Flags,
|
|
ServerName,
|
|
ServerOsVersion,
|
|
ServerPrincipleName,
|
|
ClientContext,
|
|
AuthnLevel );
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetLogonGetDirectDomain(
|
|
IN LPWSTR HostedDomainName,
|
|
IN LPWSTR TrustedDomainName,
|
|
OUT LPWSTR *DirectDomainName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the name of a domain in the enterprise and returns
|
|
the name of a domain that is one hop closer.
|
|
|
|
Arguments:
|
|
|
|
HostedDomainName - Identifies the hosted domain that this request applies to.
|
|
DomainName may be the Netbios domain name or the DNS domain name.
|
|
NULL implies the primary domain hosted by this machine.
|
|
|
|
TrustedDomainName - Identifies the domain the trust relationship is to.
|
|
DomainName may be the Netbios domain name or the DNS domain name.
|
|
|
|
DirectDomainName - Returns the DNS domain name of the domain that is
|
|
one hop closer to TrustedDomainName. If there is a direct trust to
|
|
TrustedDomainName, NULL is returned.
|
|
The buffer must be freed using I_NetLogonFree.
|
|
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS: The auth data was successfully returned.
|
|
|
|
STATUS_NO_MEMORY: There is not enough memory to complete the operation
|
|
|
|
STATUS_NETLOGON_NOT_STARTED: Netlogon is not running
|
|
|
|
STATUS_NO_SUCH_DOMAIN: HostedDomainName does not correspond to a hosted domain, OR
|
|
TrustedDomainName is not a trusted domain.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetLogonGetDirectDomain)(
|
|
HostedDomainName,
|
|
TrustedDomainName,
|
|
DirectDomainName );
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetLogonGetDirectDomain returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
I_NetNotifyNtdsDsaDeletion (
|
|
IN LPWSTR DnsDomainName,
|
|
IN GUID *DomainGuid,
|
|
IN GUID *DsaGuid,
|
|
IN LPWSTR DnsHostName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called by the DS to indicate that a NTDS-DSA object
|
|
is being deleted.
|
|
|
|
This function is called on the DC that the object is originally deleted on.
|
|
It is not called when the deletion is replicated to other DCs.
|
|
|
|
Arguments:
|
|
|
|
DnsDomainName - DNS domain name of the domain the DC was in.
|
|
This need not be a domain hosted by this DC.
|
|
|
|
DomainGuid - Domain Guid of the domain specified by DnsDomainName
|
|
|
|
DsaGuid - GUID of the NtdsDsa object that is being deleted.
|
|
|
|
DnsHostName - DNS host name of the DC whose NTDS-DSA object is being deleted.
|
|
|
|
Return Value:
|
|
|
|
Status of the operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NtStatus = (*pI_NetNotifyNtdsDsaDeletion)(
|
|
DnsDomainName,
|
|
DomainGuid,
|
|
DsaGuid,
|
|
DnsHostName );
|
|
|
|
#if DBG
|
|
|
|
if( !NT_SUCCESS(NtStatus) ) {
|
|
DbgPrint("[Security Process] I_NetNotifyNtdsDsaDeletion returns 0x%lx \n",
|
|
NtStatus);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
return( NtStatus );
|
|
}
|
|
|
|
NET_API_STATUS
|
|
I_NetLogonAddressToSiteName(
|
|
IN PSOCKET_ADDRESS SocketAddress,
|
|
OUT LPWSTR *SiteName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function translates a socket addresses to site name.
|
|
|
|
Arguments:
|
|
|
|
SocketAddress -- the requested socket address
|
|
|
|
SiteName -- the corresponding site name
|
|
|
|
Return Value:
|
|
|
|
Status of the operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
NET_API_STATUS NetStatus;
|
|
|
|
//
|
|
// Load netlogon.dll if it hasn't already been loaded.
|
|
//
|
|
|
|
if( NetlogonDllHandle == NULL ) {
|
|
if( (NtStatus = NlLoadNetlogonDll()) != STATUS_SUCCESS ) {
|
|
return( NtStatus );
|
|
}
|
|
}
|
|
|
|
NetStatus = (*pI_NetLogonAddressToSiteName)(SocketAddress,
|
|
SiteName );
|
|
|
|
return( NetStatus );
|
|
}
|