|
|
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <lm.h>
#include <lmdfs.h>
#include <netdfs.h>
#include <DfsServerLibrary.hxx>
#include <validc.h>
#include "ReferralServerLog.hxx"
//
// logging specific includes
//
#include "apisupport.tmh"
extern ULONG Flags; CRITICAL_SECTION DfsApiLock; BOOL DfsLockInitialized = FALSE; BOOL ServerListen = FALSE;
#define DFS_API_START() \
EnterCriticalSection( &DfsApiLock ); \ _try \ {
#define DFS_API_END() \
} _finally { \ LeaveCriticalSection( &DfsApiLock); \ }
extern DFSSTATUS DfsEnum( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, OUT LPBYTE *pBuffer, OUT LPDWORD pEntriesRead, IN OUT LPDWORD pResumeHandle);
NET_API_STATUS DfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle);
//+----------------------------------------------------------------------------
//
// Function: NetrDfsManagerGetVersion
//
// Synopsis: Returns the version of this server side implementation.
//
// Arguments: None.
//
// Returns: The version number.
//
//-----------------------------------------------------------------------------
DWORD NetrDfsManagerGetVersion() { DWORD Version = 4;
return( Version ); }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsAdd
// Synopsis:
//
// Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or
// to which a replica should be added.
// [ServerName] -- Name of server backing the volume.
// [ShareName] -- Name of share on ServerName backing the volume.
// [Comment] -- Comment associated with this volume, only used
// when DFS_ADD_VOLUME is specified.
// [Flags] -- If DFS_ADD_VOLUME, a new volume will be created.
// If DFS_ADD_LINK, a new link to another Dfs will be
// create. If 0, a replica will be added.
//
// Returns: [NERR_Success] -- Operation succeeded.
//
// Error other wise.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsAdd( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN LPWSTR Comment, IN DWORD Flags) { NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs Add %ws %ws %ws\n", DfsEntryPath, ServerName, ShareName);
DFS_API_START();
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsAdd( DfsEntryPath, ServerName, ShareName, Comment, Flags ); }
DFS_API_END();
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add %ws, Status 0x%x\n", DfsEntryPath, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsAdd2
//
// Synopsis: Adds a volume/replica/link to this Dfs.
//
// Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or
// to which a replica should be added.
// [DcName] -- Name of Dc to use
// [ServerName] -- Name of server backing the volume.
// [ShareName] -- Name of share on ServerName backing the volume.
// [Comment] -- Comment associated with this volume, only used
// when DFS_ADD_VOLUME is specified.
// [Flags] -- If DFS_ADD_VOLUME, a new volume will be created.
// If DFS_ADD_LINK, a new link to another Dfs will be
// create. If 0, a replica will be added.
// [ppRootList] -- On success, returns a list of roots that need to be
// informed of the change in the DS object
//
// Returns: [NERR_Success] -- Operation succeeded.
//
// Erroroce otherwise.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsAdd2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN LPWSTR Comment, IN DWORD Flags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs Add2 %ws DC:%ws Server:%ws Share:%ws\n", DfsEntryPath, DcName, ServerName, ShareName);
DFS_API_START();
//
// For now, we dont use DC name or pprootlist. We will use
// this once we implement domain dfs.
//
UNREFERENCED_PARAMETER( DcName ); UNREFERENCED_PARAMETER( ppRootList );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsAdd( DfsEntryPath, ServerName, ShareName, Comment, Flags ); }
DFS_API_END();
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add2 %ws, Status 0x%x\n", DfsEntryPath, Status); return Status;
}
//+----------------------------------------------------------------------------
//
// Function: NetrDfsGetDcAddress
//
// Synopsis: Gets the DC to go to so that we can create an FtDfs object for
// this server.
//
// Arguments: [ServerName] -- Name of server backing the volume.
// [DcName] -- Dc to use
// [IsRoot] -- TRUE if this server is a Dfs root, FALSE otherwise
// [Timeout] -- Timeout, in sec, that the server will stay with this DC
//
// Returns: [NERR_Success] -- Operation succeeded.
//
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsGetDcAddress( IN LPWSTR ServerName, IN OUT LPWSTR *DcName, IN OUT BOOLEAN *IsRoot, IN OUT ULONG *Timeout) { NET_API_STATUS Status = ERROR_SUCCESS;
UNREFERENCED_PARAMETER(ServerName);
//
// Currently, not supported
//
if(DcName == NULL) { Status = ERROR_INVALID_PARAMETER; return Status; }
*DcName = (LPWSTR)MIDL_user_allocate(4); if (*DcName == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { (*DcName)[0] = L' '; (*DcName)[1] = 0; }
if(IsRoot) { *IsRoot = FALSE; }
if(Timeout) { *Timeout = 1000; }
return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsSetDcAddress
//
// Synopsis: Sets the DC to go to for the dfs blob
//
// Arguments: [ServerName] -- Name of server backing the volume.
// [DcName] -- Dc to use
// [Timeout] -- Time, in sec, to stay with that DC
//
// Returns: [NERR_Success] -- Operation succeeded.
//
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsSetDcAddress( IN LPWSTR ServerName, IN LPWSTR DcName, IN ULONG Timeout, IN DWORD Flags) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(Timeout); UNREFERENCED_PARAMETER(Flags);
//
// Currently, not supported
//
return ERROR_SUCCESS; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsFlushFtTable
//
// Synopsis: Flushes an FtDfs entry from the FtDfs cache
//
// Arguments: [DcName] -- Dc to use
// [FtDfsName] -- Name of FtDfs
//
// Returns: [NERR_Success] -- Operation succeeded.
//
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsFlushFtTable( IN LPWSTR DcName, IN LPWSTR FtDfsName) { UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(FtDfsName);
//
// This will NEVER be supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsAddStdRoot
//
// Synopsis: Creates a new Std Dfs
//
// Arguments: [ServerName] -- Name of server backing the volume.
// [RootShare] -- Name of share on ServerName backing the volume.
// [Comment] -- Comment associated with this root.
// [Flags] -- Flags for the operation
//
// Returns: [NERR_Success] -- Operation succeeded.
//
// [NERR_DfsInternalCorruption] -- An internal database
// corruption was encountered while executing this
// operation.
//
// [ERROR_OUTOFMEMORY] -- Out of memory condition.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsAddStdRoot( IN LPWSTR ServerName, IN LPWSTR RootShare, IN LPWSTR Comment, IN DWORD ApiFlags) { NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs Add Std Root Server:%ws, Share:%ws\n", ServerName, RootShare); DFS_API_START();
if (Flags & DFS_LOCAL_NAMESPACE) { ServerName = NULL; } //
// Add a standalone root.
//
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsAddStandaloneRoot( ServerName, RootShare, Comment, ApiFlags ); }
DFS_API_END();
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add Std Root %ws\n", RootShare); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsAddStdRootForced
//
// Synopsis: Creates a new Std Dfs
//
// Arguments: [ServerName] -- Name of server backing the volume.
// [RootShare] -- Name of share on ServerName backing the volume.
// [Comment] -- Comment associated with this root.
// [Share] -- drive:\dir behind the share
//
// Returns: [NERR_Success] -- Operation succeeded.
//
// [ERROR_OUTOFMEMORY] -- Out of memory condition.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsAddStdRootForced( IN LPWSTR ServerName, IN LPWSTR RootShare, IN LPWSTR Comment, IN LPWSTR Share) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(RootShare); UNREFERENCED_PARAMETER(Comment); UNREFERENCED_PARAMETER(Share); //
// This will probably be never supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsRemove (Obsolete)
//
// Synopsis: Deletes a volume/replica/link from the Dfs.
//
// Arguments: [DfsEntryPath] -- Entry path of the volume to operate on.
// [ServerName] -- If specified, indicates the replica of the
// volume to operate on.
// [ShareName] -- If specified, indicates the share on the
// server to operate on.
// [Flags] -- Flags for the operation
//
// Returns: [NERR_Success] -- Operation successful.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsRemove( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName) { NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs remove %ws\n", DfsEntryPath); //
// call DfsRemove to do this operation.
//
DFS_API_START();
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsRemove( DfsEntryPath, ServerName, ShareName ); }
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove %ws, Status %x\n", DfsEntryPath, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsRemove2
//
// Synopsis: Deletes a volume/replica/link from the Dfs.
//
// Arguments: [DfsEntryPath] -- Entry path of the volume to operate on.
// [DcName] -- Name of Dc to use
// [ServerName] -- If specified, indicates the replica of the
// volume to operate on.
// [ShareName] -- If specified, indicates the share on the
// server to operate on.
// [Flags] -- Flags for the operation
// [ppRootList] -- On success, returns a list of roots that need to be
// informed of the change in the DS object
//
// Returns: [NERR_Success] -- Operation successful.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsRemove2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN PDFSM_ROOT_LIST *ppRootList) { UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(ppRootList); NET_API_STATUS Status = ERROR_SUCCESS;
//
// For now we ignore the DcName and rootlist, these are needed
// when we implement dom dfs.
//
DFS_TRACE_HIGH( API, "Net Dfs remove2 %ws\n", DfsEntryPath);
DFS_API_START( );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsRemove( DfsEntryPath, ServerName, ShareName ); }
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove2 %ws, Status %x\n", DfsEntryPath, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsRemoveStdRoot
//
// Synopsis: Deletes a Dfs root
//
// Arguments: [ServerName] -- The server to remove.
// [RootShare] -- The Root share hosting the Dfs/FtDfs
// [Flags] -- Flags for the operation
//
// Returns: [NERR_Success] -- Operation successful.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsRemoveStdRoot( IN LPWSTR ServerName, IN LPWSTR RootShare, IN DWORD Flags) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(Flags); NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs remove std root %ws\n", RootShare); DFS_API_START( );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsDeleteStandaloneRoot( ServerName, RootShare ); }
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove std root %ws, Status %x\n", RootShare, Status);
return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsSetInfo (Obsolete)
//
// Synopsis: Sets the comment, volume state, or replica state.
//
// Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is
// to be set.
// [ServerName] -- If specified, the name of the server whose
// state is to be set.
// [ShareName] -- If specified, the name of the share on
// ServerName whose state is to be set.
// [Level] -- Level of DfsInfo
// [DfsInfo] -- The actual Dfs info.
//
// Returns: [NERR_Success] -- Operation completed successfully.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsSetInfo( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, IN LPDFS_INFO_STRUCT pDfsInfo) { NET_API_STATUS Status = ERROR_SUCCESS; NET_API_STATUS AccessStatus; DFS_TRACE_HIGH( API, "Net Dfs set info %ws\n", DfsEntryPath); DFS_API_START( );
//
// we have to allow resynchronize events from every one.
// So do the access check for all calls except the resychronize.
//
AccessStatus = AccessImpersonateCheckRpcClient(); Status = DfsSetInfoCheckAccess( DfsEntryPath, ServerName, ShareName, Level, (LPBYTE)pDfsInfo, AccessStatus );
DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsSetInfo2
//
// Synopsis: Sets the comment, volume state, or replica state.
//
// Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is
// to be set.
// [ServerName] -- If specified, the name of the server whose
// state is to be set.
// [ShareName] -- If specified, the name of the share on
// ServerName whose state is to be set.
// [Level] -- Level of DfsInfo
// [DfsInfo] -- The actual Dfs info.
//
// Returns: [NERR_Success] -- Operation completed successfully.
//
// [ERROR_INVALID_LEVEL] -- Level != 100 , 101, or 102
//
// [ERROR_INVALID_PARAMETER] -- DfsEntryPath invalid, or
// ShareName specified without ServerName.
//
// [NERR_DfsNoSuchVolume] -- DfsEntryPath does not correspond to
// a valid Dfs volume.
//
// [NERR_DfsNoSuchShare] -- The indicated ServerName/ShareName do
// not support this Dfs volume.
//
// [NERR_DfsInternalCorruption] -- Internal database corruption
// encountered while executing operation.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsSetInfo2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, IN LPDFS_INFO_STRUCT pDfsInfo, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS;
UNREFERENCED_PARAMETER(ppRootList); UNREFERENCED_PARAMETER(DcName);
DFS_TRACE_HIGH( API, "Net Dfs set info2 %ws\n", DfsEntryPath); //
// DcName and rootlist not supported, for now.
//
DFS_API_START( );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsSetInfo( DfsEntryPath, ServerName, ShareName, Level, (LPBYTE)pDfsInfo ); }
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status);
return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsGetInfo
//
// Synopsis: Server side implementation of the NetDfsGetInfo.
//
// Arguments: [DfsEntryPath] -- Entry Path of volume for which info is
// requested.
//
// [ServerName] -- Name of server which supports this volume
// and for which info is requested.
//
// [ShareName] -- Name of share on ServerName which supports this
// volume.
//
// [Level] -- Level of Info requested.
//
// [DfsInfo] -- On successful return, contains a pointer to the
// requested DFS_INFO_x struct.
//
// Returns: [NERR_Success] -- If successfully returned requested info.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsGetInfo( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, OUT LPDFS_INFO_STRUCT pDfsInfo) { LONG BufferSize = 0; LONG SizeRequired = 0; ULONG MaxRetry = 0; NET_API_STATUS Status = ERROR_SUCCESS; PDFS_INFO_1 pInfo1 = NULL;
UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(ShareName);
DFS_TRACE_HIGH( API, "Net Dfs get info %ws\n", DfsEntryPath);
MaxRetry = 5; BufferSize = sizeof(DFS_INFO_STRUCT);
DFS_API_START( );
do { pInfo1 = (PDFS_INFO_1)MIDL_user_allocate(BufferSize); if (pInfo1 == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { Status = DfsGetInfo( DfsEntryPath, Level, (LPBYTE)pInfo1, BufferSize, &SizeRequired );
if (Status != ERROR_SUCCESS) { MIDL_user_free( pInfo1 ); }
if (Status == ERROR_BUFFER_OVERFLOW) { BufferSize = SizeRequired; } } } while ( (Status == ERROR_BUFFER_OVERFLOW) && (MaxRetry--) );
if (Status == ERROR_SUCCESS) { pDfsInfo->DfsInfo1 = pInfo1; }
DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs get info %ws, Status %x\n", DfsEntryPath, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsEnum
//
// Synopsis: The server side implementation of the NetDfsEnum public API
//
// Arguments: [Level] -- The level of info struct desired.
// [PrefMaxLen] -- Preferred maximum length of output buffer.
// 0xffffffff means no limit.
// [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info
// structs will be returned.
// [ResumeHandle] -- If 0, the enumeration will begin from the
// start. On return, the resume handle will be an opaque
// cookie that can be passed in on subsequent calls to
// resume the enumeration.
//
// Returns: [NERR_Success] -- Successfully retrieved info.
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsEnum( IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) { NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs enum %d\n", Level); DFS_API_START(); //
// We just call NetRDfsEnumEx with a null pathname.
//
Status = DfsEnumEx( NULL, Level, PrefMaxLen, pDfsEnum, pResumeHandle );
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum %d, Status %x\n", Level, Status); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsEnumEx
//
// Synopsis: The DC implementation of the NetDfsEnum public API
//
// Arguments: [DfsName] -- The Dfs to enumerate (\\domainname\ftdfsname)
// [Level] -- The level of info struct desired.
// [PrefMaxLen] -- Preferred maximum length of output buffer.
// 0xffffffff means no limit.
// [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info
// structs will be returned.
// [ResumeHandle] -- If 0, the enumeration will begin from the
// start. On return, the resume handle will be an opaque
// cookie that can be passed in on subsequent calls to
// resume the enumeration.
//
// Returns: [NERR_Success] -- Successfully retrieved info.
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) {
NET_API_STATUS Status = ERROR_SUCCESS;
DFS_TRACE_HIGH( API, "Net Dfs enum ex %ws\n", DfsName); DFS_API_START ();
Status = DfsEnumEx( DfsName, Level, PrefMaxLen, pDfsEnum, pResumeHandle);
DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum ex %ws, Status %x\n", DfsName, Status);
return Status;
}
NET_API_STATUS DfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) { DWORD EntriesRead = 0; NET_API_STATUS Status = 0; LPDFS_INFO_1 pInfo1 = NULL;
if ((pDfsEnum == NULL) || (pDfsEnum->DfsInfoContainer.DfsInfo1Container == NULL)) { return ERROR_INVALID_PARAMETER; }
Status = DfsEnum(DfsName, Level, PrefMaxLen, (LPBYTE *) &pInfo1, &EntriesRead, pResumeHandle); if (Status == ERROR_SUCCESS) { pDfsEnum->DfsInfoContainer.DfsInfo1Container->Buffer = (LPDFS_INFO_1) pInfo1; pDfsEnum->DfsInfoContainer.DfsInfo1Container->EntriesRead = EntriesRead, pDfsEnum->Level = Level; }
return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsManagerGetConfigInfo
//
// Synopsis: RPC Interface method that returns the config info for a
// Dfs volume for a given server
//
// Arguments: [wszServer] -- Name of server requesting the info. This
// server is assumed to be requesting the info for
// verification of its local volume knowledge.
// [wszLocalVolumeEntryPath] -- Entry path of local volume.
// [idLocalVolume] -- The guid of the local volume.
// [ppRelationInfo] -- The relation info is allocated and
// returned here.
//
// Returns: STATUS_NOT_SUPPORTED
//
//-----------------------------------------------------------------------------
extern "C" DWORD NetrDfsManagerGetConfigInfo( IN LPWSTR wszServer, IN LPWSTR wszLocalVolumeEntryPath, IN GUID idLocalVolume, OUT LPDFSM_RELATION_INFO *ppRelationInfo) { UNREFERENCED_PARAMETER( wszServer); UNREFERENCED_PARAMETER( wszLocalVolumeEntryPath); UNREFERENCED_PARAMETER( idLocalVolume); UNREFERENCED_PARAMETER( ppRelationInfo);
//
// This will probably be never supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsManagerSendSiteInfo
//
// Synopsis: RPC Interface method that reports the site information for a
// Dfs storage server.
//
// Arguments: [wszServer] -- Name of server sending the info.
// [pSiteInfo] -- The site info is here.
//
// Returns: STATUS_NOT_SUPPORTED
//
//-----------------------------------------------------------------------------
extern "C" DWORD NetrDfsManagerSendSiteInfo( IN LPWSTR wszServer, IN LPDFS_SITELIST_INFO pSiteInfo) { UNREFERENCED_PARAMETER( wszServer); UNREFERENCED_PARAMETER( pSiteInfo);
//
// This will probably be never supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsManagerInitialize
//
// Synopsis: Reinitializes the service
//
// Arguments: [ServerName] -- Name of server
// [Flags] -- Flags for the operation
//
// Returns: STATUS_NOT_SUPPORTED
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsManagerInitialize( IN LPWSTR ServerName, IN DWORD Flags) { UNREFERENCED_PARAMETER( ServerName); UNREFERENCED_PARAMETER( Flags); //
// This will probably be never supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsMove
//
// Synopsis: Moves a leaf volume to a different parent.
//
// Arguments: [DfsEntryPath] -- Current entry path of Dfs volume.
//
// [NewEntryPath] -- New entry path of Dfs volume.
//
// Returns: STATUS_NOT_SUPPORTED
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsMove( IN LPWSTR DfsEntryPath, IN LPWSTR NewDfsEntryPath) { UNREFERENCED_PARAMETER( DfsEntryPath); UNREFERENCED_PARAMETER( NewDfsEntryPath); //
// This will definitely be never supported.
//
return ERROR_NOT_SUPPORTED; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsRename
//
// Synopsis: Moves a leaf volume to a different parent.
//
// Arguments: [Path] -- Current path along the entry path of a Dfs volume.
//
// [NewPath] -- New path for current path.
//
// Returns: STATUS_NOT_SUPPORTED
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsRename( IN LPWSTR Path, IN LPWSTR NewPath) { UNREFERENCED_PARAMETER( Path); UNREFERENCED_PARAMETER( NewPath); //
// This will definitely be never supported.
//
return ERROR_NOT_SUPPORTED; }
// ====================================================================
// MIDL allocate and free
//
// These routines are used by the RPC layer to call back into our
// code to allocate or free memory.
//
// ====================================================================
PVOID MIDL_user_allocate(size_t len) { return malloc(len); }
VOID MIDL_user_free(void * ptr) { free(ptr); }
//+-------------------------------------------------------------------------
//
// Function: RpcInit - Initialize the RPC for this server.
//
// Arguments: NONE
//
// Returns: Status
// ERROR_SUCCESS if we initialized without errors
//
// Description: This routine sets up the RPC server to listen to the
// api requests originating from the clients.
//
//--------------------------------------------------------------------------
DWORD DfsApiInit() { RPC_STATUS Status = 0; LPWSTR ProtocolSequence = L"ncacn_np"; PVOID Security = NULL; /* let the security subsystem assign appropriate SD */ LPWSTR Endpoint = L"\\pipe\\netdfs"; unsigned int cMinCalls = 1; unsigned int cMaxCalls = RPC_C_LISTEN_MAX_CALLS_DEFAULT; unsigned int fDontWait = TRUE; DfsLockInitialized = InitializeCriticalSectionAndSpinCount( &DfsApiLock, 0 ); if(DfsLockInitialized == FALSE) { Status = GetLastError(); return Status; }
//
// We register our protocol, and startup a server to listen to RPC
// requests. A new server thread is started, so that our thread
// can return back to the caller.
//
Status = RpcServerUseProtseqEpW((USHORT *)ProtocolSequence, cMaxCalls, (USHORT *)Endpoint, Security); if (Status == ERROR_SUCCESS) { Status = RpcServerRegisterIf(netdfs_ServerIfHandle, NULL, NULL);
if (Status == ERROR_SUCCESS) { Status = RpcServerListen(cMinCalls, cMaxCalls, fDontWait); if (Status == RPC_S_OK ) { ServerListen = TRUE; } } } return Status; }
void DfsApiShutDown(void) { RPC_STATUS Status = RPC_S_OK;
//
// stop server listen.
//
if(ServerListen) {
Status = RpcMgmtStopServerListening(0);
//
// wait for all RPC threads to go away.
//
if( Status == RPC_S_OK) { Status = RpcMgmtWaitServerListen(); }
ServerListen = FALSE; }
Status = RpcServerUnregisterIf(netdfs_ServerIfHandle, NULL, TRUE); // wait for calls to complete
if(DfsLockInitialized) { DeleteCriticalSection(&DfsApiLock); } }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsAddFtRoot
//
// Synopsis: Creates a new FtDfs, or joins a Server into an FtDfs
//
// Arguments: [ServerName] -- Name of server backing the volume.
// [DcName] -- DC to use
// [RootShare] -- Name of share on ServerName backing the volume.
// [FtDfsName] -- The Name of the FtDfs to create/join
// [Comment] -- Comment associated with this root.
// [Flags] -- Flags for the operation
// [ppRootList] -- On success, returns a list of roots that need to be
// informed of the change in the DS object
//
// Returns: [NERR_Success] -- Operation succeeded.
//
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsAddFtRoot( IN LPWSTR ServerName, IN LPWSTR DcName, IN LPWSTR RootShare, IN LPWSTR FtDfsName, IN LPWSTR Comment, IN LPWSTR ConfigDN, IN BOOLEAN NewFtDfs, IN DWORD ApiFlags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS; UNREFERENCED_PARAMETER( ConfigDN);
if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) || (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) || (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) || (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) ) { return ERROR_INVALID_PARAMETER; }
DFS_TRACE_HIGH( API, "Net Dfs Add FT Root %ws\n", RootShare); DFS_API_START( );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsAddADBlobRoot( ServerName, DcName, RootShare, FtDfsName, Comment, NewFtDfs, ApiFlags, (PVOID)ppRootList ); }
DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add AD blob Root %ws\n", RootShare); return Status; }
//+----------------------------------------------------------------------------
//
// Function: NetrDfsRemoveFtRoot
//
// Synopsis: Deletes a root from an FtDfs.
//
// Arguments: [ServerName] -- The server to remove.
// [DcName] -- DC to use
// [RootShare] -- The Root share hosting the Dfs/FtDfs
// [FtDfsName] -- The FtDfs to remove the root from.
// [Flags] -- Flags for the operation
// [ppRootList] -- On success, returns a list of roots that need to be
// informed of the change in the DS object
//
// Returns: [NERR_Success] -- Operation successful.
//
//
//-----------------------------------------------------------------------------
extern "C" NET_API_STATUS NetrDfsRemoveFtRoot( IN LPWSTR ServerName, IN LPWSTR DcName, IN LPWSTR RootShare, IN LPWSTR FtDfsName, IN DWORD ApiFlags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS;
if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) || (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) || (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) || (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) ) { return ERROR_INVALID_PARAMETER; }
DFS_TRACE_HIGH( API, "Net Dfs Remove FT Root %ws\n", RootShare); DFS_API_START( );
Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) {
Status = DfsDeleteADBlobRoot( ServerName, DcName, RootShare, FtDfsName, ApiFlags, (PVOID)ppRootList ); } DFS_API_END( );
DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Remove AD blob Root %ws\n", RootShare); return Status; }
|