Leaked source code of windows server 2003
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.
 
 
 
 
 
 

460 lines
16 KiB

//================================================================================
// Copyright (C) 1997 Microsoft Corporation
// Author: RameshV
// Description: Actual stubs that are the equivalent the rpcapi1.c and rpcapi2.c
// in the server\server directory.. (or more accurately, the implementations are
// the same as for the functions defined in server\client\dhcpsapi.def)
// NOTE: THE FOLLOWING FUNCTIONS ARE NOT RPC, BUT THEY BEHAVE JUST THE SAME AS
// THE DHCP RPC CALLS, EXCEPT THEY ACCESS THE DS DIRECTLY.
//================================================================================
#include <hdrmacro.h>
#include <store.h>
#include <dhcpmsg.h>
#include <wchar.h>
#include <dhcpbas.h>
#include <mm\opt.h>
#include <mm\optl.h>
#include <mm\optdefl.h>
#include <mm\optclass.h>
#include <mm\classdefl.h>
#include <mm\bitmask.h>
#include <mm\reserve.h>
#include <mm\range.h>
#include <mm\subnet.h>
#include <mm\sscope.h>
#include <mm\oclassdl.h>
#include <mm\server.h>
#include <mm\address.h>
#include <mm\server2.h>
#include <mm\memfree.h>
#include <mmreg\regutil.h>
#include <mmreg\regread.h>
#include <mmreg\regsave.h>
#include <dhcpapi.h>
#include <delete.h>
#include <st_srvr.h>
#include <rpcapi2.h>
//================================================================================
// global variables..
//================================================================================
BOOL
StubInitialized = FALSE;
STORE_HANDLE hDhcpC, hDhcpRoot;
CRITICAL_SECTION DhcpDsDllCriticalSection;
//================================================================================
// THE FOLLOWING FUNCTIONS HAVE BEEN COPIED OVER FROM RPCAPI1.C (IN THE
// DHCP\SERVER\SERVER DIRECTORY).
//================================================================================
#undef DhcpPrint
#define DhcpPrint(X)
#define DhcpAssert(X)
//================================================================================
// helper routines
//================================================================================
VOID
MemFreeFunc( // free memory
IN OUT LPVOID Mem
)
{
MemFree(Mem);
}
//
// ErrorNotInitialized used to be ZERO.. but why would we NOT return an error?
// so changed it to return errors..
//
#define ErrorNotInitialized Err
#define STUB_NOT_INITIALIZED(Err) ( !StubInitialized && ((Err) = StubInitialize()))
//DOC StubInitialize initializes all the modules involved in the dhcp ds dll.
//DOC It also sets a global variable StubInitialized to TRUE to indicate that
//DOC initialization went fine. This should be called as part of DllInit so that
//DOC everything can be done at this point..
DWORD
StubInitialize( // initialize all global vars
VOID
)
{
DWORD Err,Err2;
STORE_HANDLE ConfigC;
if( StubInitialized ) return ERROR_SUCCESS; // already initialized
Err = Err2 = ERROR_SUCCESS;
EnterCriticalSection( &DhcpDsDllCriticalSection );
do {
if( StubInitialized ) break;
Err = StoreInitHandle(
/* hStore */ &ConfigC,
/* Reserved */ DDS_RESERVED_DWORD,
/* ThisDomain */ NULL, // current domain
/* UserName */ NULL, // current user
/* Password */ NULL, // current credentials
/* AuthFlags */ ADS_SECURE_AUTHENTICATION | ADS_USE_SIGNING | ADS_USE_SEALING
);
if( ERROR_SUCCESS != Err ) {
Err = ERROR_DDS_NO_DS_AVAILABLE; // could not get config hdl
break;
}
Err = DhcpDsGetDhcpC(
DDS_RESERVED_DWORD, &ConfigC, &hDhcpC
);
if( ERROR_SUCCESS == Err ) {
Err2 = DhcpDsGetRoot( // now try to get root handle
DDS_FLAGS_CREATE, &ConfigC, &hDhcpRoot
);
}
StoreCleanupHandle(&ConfigC, DDS_RESERVED_DWORD);
} while (0);
if( ERROR_SUCCESS != Err2 ) { // could not get dhcp root hdl
DhcpAssert(ERROR_SUCCESS == Err);
StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
Err = Err2;
}
StubInitialized = (ERROR_SUCCESS == Err );
LeaveCriticalSection( &DhcpDsDllCriticalSection );
return Err;
}
//DOC StubCleanup de-initializes all the modules involved in the dhcp ds dll.
//DOC its effect is to undo everything done by StubInitialize
VOID
StubCleanup( // undo StubInitialize
VOID
)
{
if( ! StubInitialized ) return; // never initialized anyways
EnterCriticalSection(&DhcpDsDllCriticalSection);
if( StubInitialized ) {
StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
StoreCleanupHandle(&hDhcpRoot, DDS_RESERVED_DWORD);
StubInitialized = FALSE;
}
LeaveCriticalSection(&DhcpDsDllCriticalSection);
}
//DOC DhcpDsLock is not yet implemented
DWORD
DhcpDsLock( // lock the ds
IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object to lock via
)
{
EnterCriticalSection(&DhcpDsDllCriticalSection);
return ERROR_SUCCESS;
}
//DOC DhcpDsUnlock not yet implemented
VOID
DhcpDsUnlock(
IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object..
)
{
LeaveCriticalSection(&DhcpDsDllCriticalSection);
}
//DOC GetServerNameFromAddr gets the server name given ip address
DWORD
GetServerNameFromAddr( // get server name from ip addr
IN DWORD IpAddress, // look for server w/ this addr
OUT LPWSTR *ServerName // fill this with matching name
)
{
DWORD Err, Err2;
ARRAY Servers;
ARRAY_LOCATION Loc;
PEATTRIB ThisAttrib;
LPWSTR ThisStr, AllocStr;
MemArrayInit(&Servers);
Err = DhcpDsGetLists // get list of servers
(
/* Reserved */ DDS_RESERVED_DWORD,
/* hStore */ &hDhcpRoot,
/* RecursionDepth */ 0xFFFFFFFF,
/* Servers */ &Servers, // array of PEATTRIB 's
/* Subnets */ NULL,
/* IpAddress */ NULL,
/* Mask */ NULL,
/* Ranges */ NULL,
/* Sites */ NULL,
/* Reservations */ NULL,
/* SuperScopes */ NULL,
/* OptionDescription */ NULL,
/* OptionsLocation */ NULL,
/* Options */ NULL,
/* Classes */ NULL
);
if( ERROR_SUCCESS != Err ) return Err;
ThisStr = NULL;
for( // find name for ip-address
Err = MemArrayInitLoc(&Servers,&Loc)
; ERROR_FILE_NOT_FOUND != Err ;
Err = MemArrayNextLoc(&Servers, &Loc)
) {
//= require ERROR_SUCCESS == Err
Err = MemArrayGetElement(&Servers, &Loc, &ThisAttrib);
//= require ERROR_SUCCESS == Err && NULL != ThisAttrib
if( !IS_STRING1_PRESENT(ThisAttrib) || // no name for this server
!IS_ADDRESS1_PRESENT(ThisAttrib) ) { // no address for this server
continue; //= ds inconsistent
}
ThisStr = ThisAttrib->String1;
break;
}
AllocStr = NULL;
if( NULL == ThisStr ) { // didnt find server name
Err = ERROR_FILE_NOT_FOUND;
} else { // found the server name
AllocStr = MemAlloc(sizeof(WCHAR)*(1+wcslen(ThisStr)));
if( NULL == AllocStr ) { // couldnt alloc mem?
Err = ERROR_NOT_ENOUGH_MEMORY;
} else { // now just copy the str over
wcscpy(AllocStr, ThisStr);
Err = ERROR_SUCCESS;
}
}
MemArrayFree(&Servers, MemFreeFunc);
*ServerName = AllocStr;
return Err;
}
//================================================================================
// the following functions are NOT based on RPC, but actually direct calls to
// the DS. But, they have the same interface as the RPC stubs in dhcpsapi.dll.
//================================================================================
BOOLEAN
DllMain(
IN HINSTANCE DllHandle,
IN ULONG Reason,
IN PCONTEXT Context OPTIONAL
)
/*++
Routine Description:
This routine is the standard DLL initialization
routine and all it does is intiialize a critical section
for actual initialization to be done at startup elsewhere.
Arguments:
DllHandle -- handle to current module
Reason -- reason for DLL_PROCESS_ATTACH.. DLL_PROCESS_DETACH
Return Value:
TRUE -- success, FALSE -- failure
--*/
{
if( DLL_PROCESS_ATTACH == Reason ) {
//
// First disable further calls to DllInit
//
if( !DisableThreadLibraryCalls( DllHandle ) ) return FALSE;
//
// Now try to create critical section
//
try {
InitializeCriticalSection(&DhcpDsDllCriticalSection);
} except ( EXCEPTION_EXECUTE_HANDLER ) {
// shouldnt happen but you never know.
return FALSE;
}
} else if( DLL_PROCESS_DETACH == Reason ) {
//
// Cleanup the initialization critical section
//
DeleteCriticalSection(&DhcpDsDllCriticalSection);
}
//
// InitializeCriticalSection does not fail, just throws exception..
// so we always return success.
//
return TRUE;
}
//================================================================================
// DS only NON-rpc stubs
//================================================================================
//BeginExport(function)
//DOC DhcpEnumServersDS lists the servers found in the DS along with the
//DOC addresses and other information. The whole server is allocated as a blob,
//DOC and should be freed in one shot. No parameters are currently used, other
//DOC than Servers which will be an OUT parameter only.
DWORD
DhcpEnumServersDS(
IN DWORD Flags,
IN LPVOID IdInfo,
OUT LPDHCP_SERVER_INFO_ARRAY *Servers,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2, Size,i;
LPDHCPDS_SERVERS DhcpDsServers;
AssertRet(Servers, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
*Servers = NULL;
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
DhcpDsServers = NULL;
Err = DhcpDsEnumServers // get the list of servers
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServersInfo */ &DhcpDsServers
);
DhcpDsUnlock(&hDhcpRoot);
if( ERROR_SUCCESS != Err ) return Err; // return err..
*Servers = DhcpDsServers;
return ERROR_SUCCESS;
}
//BeginExport(function)
//DOC DhcpAddServerDS adds a particular server to the DS. If the server exists,
//DOC then, this returns error. If the server does not exist, then this function
//DOC adds the server in DS, and also uploads the configuration from the server
//DOC to the ds.
DWORD
DhcpAddServerDS(
IN DWORD Flags,
IN LPVOID IdInfo,
IN LPDHCP_SERVER_INFO NewServer,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2;
WCHAR TmpBuf[sizeof(L"000.000.000.000")];
AssertRet(NewServer, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsAddServer // add the new server
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ NewServer->ServerName,
/* ReservedPtr */ DDS_RESERVED_PTR,
/* IpAddress */ NewServer->ServerAddress,
/* State */ Flags
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC DhcpDeleteServerDS deletes the servers from off the DS and recursively
//DOC deletes the server object..(i.e everything belonging to the server is deleted).
//DOC If the server does not exist, it returns an error.
DWORD
DhcpDeleteServerDS(
IN DWORD Flags,
IN LPVOID IdInfo,
IN LPDHCP_SERVER_INFO NewServer,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2;
AssertRet(NewServer, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsDelServer // del this server
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ NewServer->ServerName,
/* ReservedPtr */ DDS_RESERVED_PTR,
/* IpAddress */ NewServer->ServerAddress
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC DhcpDsInitDS initializes everything in this module.
DWORD
DhcpDsInitDS(
DWORD Flags,
LPVOID IdInfo
) //EndExport(function)
{
return StubInitialize();
}
//BeginExport(function)
//DOC DhcpDsCleanupDS uninitiailzes everything in this module.
VOID
DhcpDsCleanupDS(
VOID
) //EndExport(function)
{
StubCleanup();
}
//BeginExport(header)
//DOC This function is defined in validate.c
//DOC Only the stub is here.
DWORD
DhcpDsValidateService( // check to validate for dhcp
IN LPWSTR Domain,
IN DWORD *Addresses OPTIONAL,
IN ULONG nAddresses,
IN LPWSTR UserName,
IN LPWSTR Password,
IN DWORD AuthFlags,
OUT LPBOOL Found,
OUT LPBOOL IsStandAlone
);
//EndExport(header)
//================================================================================
// end of file
//================================================================================