mirror of https://github.com/lianthony/NT4.0
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.
563 lines
12 KiB
563 lines
12 KiB
/**********************************************************************/
|
|
/** Microsoft Windows NT **/
|
|
/** Copyright(c) Microsoft Corp., 1993 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
rpcsupp.c
|
|
|
|
This module contains support routines for the FTP Service RPC
|
|
interface.
|
|
|
|
|
|
FILE HISTORY:
|
|
KeithMo 23-Mar-1993 Created.
|
|
|
|
*/
|
|
|
|
|
|
#include "ftpdp.h"
|
|
#pragma hdrstop
|
|
#include "rpcutil.h"
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprEnumerateUsers
|
|
|
|
SYNOPSIS: Enumerates the connected users. This is a server-side
|
|
worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
pBuffer - Will receive the number of entries and a
|
|
pointer to the enumeration buffer.
|
|
|
|
RETURNS: NET_API_STATUS - Net status code, NERR_Success if OK.
|
|
|
|
HISTORY:
|
|
KeithMo 23-Mar-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprEnumerateUsers(
|
|
FTP_IMPERSONATE_HANDLE pszServer,
|
|
LPFTP_USER_ENUM_STRUCT pBuffer
|
|
)
|
|
{
|
|
APIERR err;
|
|
DWORD cbBuffer;
|
|
|
|
FTPD_ASSERT( pBuffer != NULL );
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprEnumerateUsers\n" ));
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_ENUMERATE_USERS );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprEnumerateUsers failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Lock the user database.
|
|
//
|
|
|
|
LockUserDatabase();
|
|
|
|
//
|
|
// Determine the necessary buffer size.
|
|
//
|
|
|
|
pBuffer->EntriesRead = 0;
|
|
pBuffer->Buffer = NULL;
|
|
|
|
cbBuffer = 0;
|
|
err = NERR_Success;
|
|
|
|
EnumerateUsers( pBuffer, &cbBuffer );
|
|
|
|
if( cbBuffer > 0 )
|
|
{
|
|
//
|
|
// Allocate the buffer. Note that we *must*
|
|
// use midl_user_allocate/midl_user_free.
|
|
//
|
|
|
|
pBuffer->Buffer = (FTP_USER_INFO *)MIDL_user_allocate( (unsigned int)cbBuffer );
|
|
|
|
if( pBuffer->Buffer == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Since we've got the user database locked, there
|
|
// *should* be enough room in the buffer for the
|
|
// user data. If there isn't, we've screwed up
|
|
// somewhere.
|
|
//
|
|
|
|
FTPD_REQUIRE( EnumerateUsers( pBuffer, &cbBuffer ) );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Unlock the user database before returning.
|
|
|
|
UnlockUserDatabase();
|
|
|
|
return (NET_API_STATUS)err;
|
|
|
|
} // I_FtprEnumerateUsers
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprDisconnectUser
|
|
|
|
SYNOPSIS: Disconnects a specified user. This is a server-side
|
|
worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
idUser - Identifies the user to disconnect. If 0,
|
|
then disconnect ALL users.
|
|
|
|
RETURNS: NET_API_STATUS - Net status code, NERR_Success if OK.
|
|
|
|
HISTORY:
|
|
KeithMo 23-Mar-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprDisconnectUser(
|
|
FTP_IMPERSONATE_HANDLE pszServer,
|
|
DWORD idUser
|
|
)
|
|
{
|
|
APIERR err = NERR_Success;
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprDisconnectUser\n" ));
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_DISCONNECT_USER );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprDisconnectUser failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Do it.
|
|
//
|
|
|
|
if( idUser == 0 )
|
|
{
|
|
DisconnectAllUsers();
|
|
}
|
|
else
|
|
{
|
|
if( !DisconnectUser( idUser ) )
|
|
{
|
|
err = NERR_UserNotFound;
|
|
}
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
|
|
} // I_FtprDisconnectUser
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprQueryVolumeSecurity
|
|
|
|
SYNOPSIS: Returns the current volume security masks. This is
|
|
a server-side worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
pdwReadAccess - Will receive the read access mask.
|
|
|
|
pdwWriteAccess - Will receive the write access mask.
|
|
|
|
RETURNS: NET_API_STATUS - Status code, NERR_Success if successful.
|
|
|
|
HISTORY:
|
|
KeithMo 23-Mar-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprQueryVolumeSecurity(
|
|
FTP_IMPERSONATE_HANDLE pszServer,
|
|
LPDWORD pdwReadAccess,
|
|
LPDWORD pdwWriteAccess
|
|
)
|
|
{
|
|
APIERR err;
|
|
|
|
FTPD_ASSERT( pdwReadAccess != NULL );
|
|
FTPD_ASSERT( pdwWriteAccess != NULL );
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprQueryVolumeSecurity\n" ));
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_QUERY_SECURITY );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprQueryVolumeSecurity failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Return the current access masks.
|
|
//
|
|
|
|
LockGlobals();
|
|
|
|
*pdwReadAccess = maskReadAccess;
|
|
*pdwWriteAccess = maskWriteAccess;
|
|
|
|
UnlockGlobals();
|
|
|
|
return NERR_Success;
|
|
|
|
} // I_FtprQueryVolumeSecurity
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprSetVolumeSecurity
|
|
|
|
SYNOPSIS: Sets the current volume security masks. This function
|
|
is also responsible for disconnecting any users that
|
|
no longer have read access to their current directory.
|
|
This is a server-side worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
dwReadAccess - The new read access mask.
|
|
|
|
dwWriteAccess - The new write access mask.
|
|
|
|
RETURNS: NET_API_STATUS - Status code, NERR_Success if successful.
|
|
|
|
HISTORY:
|
|
KeithMo 23-Mar-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprSetVolumeSecurity(
|
|
FTP_IMPERSONATE_HANDLE pszServer,
|
|
DWORD dwReadAccess,
|
|
DWORD dwWriteAccess
|
|
)
|
|
{
|
|
APIERR err;
|
|
DWORD maskInvalid = ~VALID_DOS_DRIVE_MASK;
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprSetVolumeSecurity\n" ));
|
|
}
|
|
|
|
//
|
|
// Validate the parameters.
|
|
//
|
|
|
|
if( ( dwReadAccess & maskInvalid ) || ( dwWriteAccess & maskInvalid ) )
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_SET_SECURITY );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprSetVolumeSecurity failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Update the registry.
|
|
//
|
|
|
|
err = WriteRegistryDword( FTPD_READ_ACCESS_MASK,
|
|
dwReadAccess );
|
|
|
|
if( err == NO_ERROR )
|
|
{
|
|
err = WriteRegistryDword( FTPD_WRITE_ACCESS_MASK,
|
|
dwWriteAccess );
|
|
}
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "cannot update access masks in registry, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Update the local masks.
|
|
//
|
|
|
|
LockGlobals();
|
|
|
|
maskReadAccess = dwReadAccess;
|
|
maskWriteAccess = dwWriteAccess;
|
|
|
|
UpdateAccessMasks();
|
|
|
|
UnlockGlobals();
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "maskReadAccess set to %08lX\n",
|
|
maskReadAccess ));
|
|
|
|
FTPD_PRINT(( "maskWriteAccess set to %08lX\n",
|
|
maskWriteAccess ));
|
|
}
|
|
|
|
//
|
|
// Blow away everyone that can no longer access their
|
|
// current directory.
|
|
//
|
|
|
|
DisconnectUsersWithNoAccess();
|
|
|
|
return NERR_Success;
|
|
|
|
} // I_FtprSetVolumeSecurity
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprQueryStatistics
|
|
|
|
SYNOPSIS: Queries the current server statistics. This is a
|
|
server-side worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
Level - Info level. Currently only level 0 is
|
|
supported.
|
|
|
|
pBuffer - Will receive a poitner to the statistics
|
|
structure.
|
|
|
|
RETURNS: NET_API_STATUS - Net status code, NERR_Success if OK.
|
|
|
|
HISTORY:
|
|
KeithMo 02-Jun-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprQueryStatistics(
|
|
FTP_IMPERSONATE_HANDLE pszServer,
|
|
DWORD Level,
|
|
LPSTATISTICS_INFO pBuffer
|
|
)
|
|
{
|
|
APIERR err;
|
|
|
|
FTPD_ASSERT( pBuffer != NULL );
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprQueryStatistics, level %lu\n", Level ));
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_QUERY_STATISTICS );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprQueryStatistics failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Return the proper statistics based on the infolevel.
|
|
//
|
|
|
|
switch( Level )
|
|
{
|
|
case 0 :
|
|
{
|
|
LPFTP_STATISTICS_0 pstats0;
|
|
|
|
pstats0 = (LPFTP_STATISTICS_0)MIDL_user_allocate( sizeof(FTP_STATISTICS_0) );
|
|
|
|
if( pstats0 == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
LockStatistics();
|
|
RtlCopyMemory( pstats0, &FtpStats, sizeof(FTP_STATISTICS_0) );
|
|
UnlockStatistics();
|
|
|
|
pBuffer->FtpStats0 = pstats0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default :
|
|
err = ERROR_INVALID_LEVEL;
|
|
break;
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
|
|
} // I_FtprQueryStatistics
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: I_FtprClearStatistics
|
|
|
|
SYNOPSIS: Clears current server statistics. This is a
|
|
server-side worker routine for RPC.
|
|
|
|
ENTRY: pszServer - Target server (unused).
|
|
|
|
RETURNS: NET_API_STATUS - Net status code, NERR_Success if OK.
|
|
|
|
HISTORY:
|
|
KeithMo 02-Jun-1993 Created.
|
|
|
|
********************************************************************/
|
|
NET_API_STATUS
|
|
I_FtprClearStatistics(
|
|
FTP_IMPERSONATE_HANDLE pszServer
|
|
)
|
|
{
|
|
APIERR err;
|
|
|
|
UNREFERENCED_PARAMETER(pszServer);
|
|
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "in I_FtprClearStatistics\n" ));
|
|
}
|
|
|
|
//
|
|
// Check for proper access.
|
|
//
|
|
|
|
err = ApiAccessCheck( FTPD_CLEAR_STATISTICS );
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
IF_DEBUG( RPC )
|
|
{
|
|
FTPD_PRINT(( "I_FtprClearStatistics failed access check, error %lu\n",
|
|
err ));
|
|
}
|
|
|
|
return (NET_API_STATUS)err;
|
|
}
|
|
|
|
//
|
|
// Clear the statistics.
|
|
//
|
|
|
|
ClearStatistics();
|
|
|
|
return (NET_API_STATUS)err;
|
|
|
|
} // I_FtprClearStatistics
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|