diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nlsecutl | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/nlsecutl')
-rw-r--r-- | private/nlsecutl/makefile | 6 | ||||
-rw-r--r-- | private/nlsecutl/nlrepl.c | 646 | ||||
-rw-r--r-- | private/nlsecutl/sources | 42 |
3 files changed, 694 insertions, 0 deletions
diff --git a/private/nlsecutl/makefile b/private/nlsecutl/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/nlsecutl/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/nlsecutl/nlrepl.c b/private/nlsecutl/nlrepl.c new file mode 100644 index 000000000..97aa041e3 --- /dev/null +++ b/private/nlsecutl/nlrepl.c @@ -0,0 +1,646 @@ +/*++ + +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 <nlrepl.h> // proto types + +#define REPLICATION_ENABLED + +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_NETGETANYDCNAME) ( + IN PUNICODE_STRING DomainName, + OUT PUNICODE_STRING Buffer + ); + +typedef NTSTATUS + (*PI_NETNOTIFYNETLOGONDLLHANDLE) ( + IN PHANDLE Role + ); + +// +// Global status +// + +#ifdef REPLICATION_ENABLED + +HANDLE NetlogonDllHandle = NULL; +PI_NETNOTIFYDELTA pI_NetNotifyDelta = NULL; +PI_NETNOTIFYROLE pI_NetNotifyRole = NULL; +PI_NETNOTIFYMACHINEACCOUNT pI_NetNotifyMachineAccount = NULL; +PI_NETGETANYDCNAME pI_NetGetAnyDcName = 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; + } + + + // + // Find the address of the I_NetNotifyDelta procedure. + // + + pI_NetNotifyDelta = (PI_NETNOTIFYDELTA) + GetProcAddress( DllHandle, "I_NetNotifyDelta" ); + + if( pI_NetNotifyDelta == NULL ) { + +#if DBG + DWORD DbgError; + + DbgError = GetLastError(); + + DbgPrint("[Security Process] can't load I_NetNotifyDelta Proc %ld \n", DbgError); +#endif // DBG + + DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND; + goto Cleanup; + } + + + // + // Find the address of the I_NetNotifyRole procedure. + // + + pI_NetNotifyRole = (PI_NETNOTIFYROLE) + GetProcAddress( DllHandle, "I_NetNotifyRole" ); + + if( pI_NetNotifyRole == NULL ) { + +#if DBG + DWORD DbgError; + + DbgError = GetLastError(); + + DbgPrint("[Security Process] can't load I_NetNotifyRole Proc %ld\n", + DbgError); +#endif // DBG + + DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND; + goto Cleanup; + } + + // + // Find the address of the I_NetNotifyMachineAccount procedure. + // + + pI_NetNotifyMachineAccount = (PI_NETNOTIFYMACHINEACCOUNT) + GetProcAddress( DllHandle, "I_NetNotifyMachineAccount" ); + + if( pI_NetNotifyMachineAccount == NULL ) { + +#if DBG + DWORD DbgError; + + DbgError = GetLastError(); + + DbgPrint("[Security Process] can't load I_NetNotifyMachineAccount Proc" + " %ld \n", DbgError); +#endif // DBG + + DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND; + goto Cleanup; + } + + + // + // Find the address of the I_NetGetAnyDcName procedure. + // + + pI_NetGetAnyDcName = (PI_NETGETANYDCNAME) + GetProcAddress( DllHandle, "I_NetGetAnyDCName" ); + + if( pI_NetGetAnyDcName == NULL ) { + +#if DBG + DWORD DbgError; + + DbgError = GetLastError(); + + DbgPrint("[Security Process] can't load I_NetGetAnyDcName Proc" + " %ld \n", DbgError); +#endif // DBG + + DllLoadStatus = STATUS_PROCEDURE_NOT_FOUND; + goto Cleanup; + } + + + // + // 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 ); +} + +#endif // REPLICATION_ENABLED + + +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. + +--*/ +{ + +#ifdef REPLICATION_ENABLED + + 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 + ); + +#if notdef + // + // Free the library so it can be replace without rebooting. ?? + // + + (VOID) FreeLibrary( NetlogonDllHandle ); + NetlogonDllHandle = NULL; +#endif // notdef + +#if notdef + + if( !NT_SUCCESS(NtStatus) ) { + DbgPrint("[Security Process] I_NetNotifyDelta returns %lx \n", + NtStatus); + } + +#endif // notdef + + return( STATUS_SUCCESS ); + +#else // REPLICATION_ENABLED + + return(STATUS_SUCCESS); + + DBG_UNREFERENCED_PARAMETER( DbType ); + DBG_UNREFERENCED_PARAMETER( ModificationCount ); + DBG_UNREFERENCED_PARAMETER( DeltaType ); + DBG_UNREFERENCED_PARAMETER( ObjectType ); + DBG_UNREFERENCED_PARAMETER( ObjectRid ); + DBG_UNREFERENCED_PARAMETER( ObjectSid ); + DBG_UNREFERENCED_PARAMETER( ObjectName ); + DBG_UNREFERENCED_PARAMETER( ReplicationImmediately ); + DBG_UNREFERENCED_PARAMETER( MemberId ); + +#endif // REPLICATION_ENABLED + +} + + +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. + +--*/ +{ + +#ifdef REPLICATION_ENABLED + + 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 ); + +#else // REPLICATION_ENABLED + + return(STATUS_SUCCESS); + + DBG_UNREFERENCED_PARAMETER( Role ); + +#endif // REPLICATION_ENABLED + +} + + +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_NetGetAnyDCName ( + IN PUNICODE_STRING DomainName, + OUT PUNICODE_STRING Buffer + ) + +/*++ + +Routine Description: + + Get the name of the any domain controller for a trusted domain. + + The domain controller found in guaranteed to have be up at one point during + this API call. The machine is also guaranteed to be a DC in the domain + specified. + + The caller of this routine should not have any locks held (it calls the + LSA back in several instances). This routine may take some time to execute. + +Arguments: + + DomainName - name of domain. + + UncDcName - Fills in the Unicode string structure to point to an allocated + buffer containing the servername of a DC of the domain. + The server name is prefixed by \\. + The buffer should be deallocated using MIDL_user_free. + +Return Value: + + STATUS_SUCCESS - Success. Buffer contains DC name prefixed by \\. + + STATUS_NO_LOGON_SERVERS - No DC could be found + + STATUS_NO_SUCH_DOMAIN - The specified domain is not a trusted domain. + + STATUS_NO_TRUST_LSA_SECRET - The client side of the trust relationship is + broken. + + STATUS_NO_TRUST_SAM_ACCOUNT - The server side of the trust relationship is + broken or the password is broken. + + STATUS_DOMAIN_TRUST_INCONSISTENT - The server that responded is not a proper + domain controller of the specified 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_NetGetAnyDcName)( + DomainName, + Buffer ); + +#if DBG + if( !NT_SUCCESS(NtStatus) ) { + DbgPrint("[Security Process] I_NetGetAnyDcName returns 0x%lx\n", + NtStatus); + } +#endif // DBG + + return( NtStatus ); +} diff --git a/private/nlsecutl/sources b/private/nlsecutl/sources new file mode 100644 index 000000000..5e758c6b5 --- /dev/null +++ b/private/nlsecutl/sources @@ -0,0 +1,42 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Madan Appiah (madana) 14-Apr-1992 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=nlsecutl +MINORCOMP=_ + +SYNCHRONIZE_BLOCK=1 + +TARGETNAME=nlrepl +TARGETPATH=\nt\public\sdk\lib +TARGETTYPE=LIBRARY + +INCLUDES=..\inc + + + +SOURCES=nlrepl.c + +UMTYPE=nt +UMTEST= +OPTIONAL_UMTEST= |