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.
1325 lines
38 KiB
1325 lines
38 KiB
|
|
#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;
|
|
}
|