333 lines
6.8 KiB
C
333 lines
6.8 KiB
C
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1993 - 1999
|
||
|
||
Module Name:
|
||
|
||
svrmgmt.c
|
||
|
||
Abstract:
|
||
|
||
We implement the server side of the remote management routines in this
|
||
file.
|
||
|
||
Author:
|
||
|
||
Michael Montague (mikemon) 14-Apr-1993
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <sysinc.h>
|
||
#include <rpc.h>
|
||
#include <mgmt.h>
|
||
|
||
|
||
int
|
||
DefaultMgmtAuthorizationFn (
|
||
IN RPC_BINDING_HANDLE ClientBinding,
|
||
IN unsigned long RequestedMgmtOperation,
|
||
OUT RPC_STATUS __RPC_FAR * Status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the default authorization function used to control remote access
|
||
to the server's management routines.
|
||
|
||
Arguments:
|
||
|
||
ClientBinding - Supplies the client binding handle of the application
|
||
which is calling this routine.
|
||
|
||
RequestedMgmtOperation - Supplies which management routine is being called.
|
||
|
||
Status - Returns RPC_S_OK.
|
||
|
||
Return Value:
|
||
|
||
A value of non-zero will be returned if the client is authorized to
|
||
call the management routine; otherwise, zero will be returned.
|
||
|
||
--*/
|
||
{
|
||
((void) ClientBinding);
|
||
|
||
*Status = RPC_S_OK;
|
||
|
||
if ( RequestedMgmtOperation != RPC_C_MGMT_STOP_SERVER_LISTEN )
|
||
{
|
||
return(1);
|
||
}
|
||
|
||
return(0);
|
||
}
|
||
|
||
RPC_MGMT_AUTHORIZATION_FN MgmtAuthorizationFn = DefaultMgmtAuthorizationFn;
|
||
|
||
|
||
RPC_STATUS RPC_ENTRY
|
||
RpcMgmtSetAuthorizationFn (
|
||
IN RPC_MGMT_AUTHORIZATION_FN AuthorizationFn
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
An application can use this routine to set the authorization function
|
||
which will be called when a remote call arrives for one of the server's
|
||
management routines, or to return to using the default (built-in)
|
||
authorizatio function.
|
||
|
||
Arguments:
|
||
|
||
AuthorizationFn - Supplies a new authorization function.
|
||
The fn may be nil, in which case the built-in auth fn
|
||
is used instead.
|
||
|
||
Return Value:
|
||
|
||
RPC_S_OK - This will always be returned.
|
||
|
||
--*/
|
||
{
|
||
if (AuthorizationFn)
|
||
{
|
||
MgmtAuthorizationFn = AuthorizationFn;
|
||
}
|
||
else
|
||
{
|
||
MgmtAuthorizationFn = DefaultMgmtAuthorizationFn;
|
||
}
|
||
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
|
||
void
|
||
rpc_mgmt_inq_if_ids (
|
||
RPC_BINDING_HANDLE binding,
|
||
rpc_if_id_vector_p_t __RPC_FAR * if_id_vector,
|
||
unsigned long __RPC_FAR * status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the management code corresponding to the rpc_mgmt_inq_if_ids
|
||
remote operation.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// If the auth fn returns false, the op is denied.
|
||
//
|
||
if ( (*MgmtAuthorizationFn)(binding, RPC_C_MGMT_INQ_IF_IDS, status) == 0 )
|
||
{
|
||
if (0 == *status || RPC_S_OK == *status)
|
||
{
|
||
*status = RPC_S_ACCESS_DENIED;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
*status = RpcMgmtInqIfIds(0, (RPC_IF_ID_VECTOR **) if_id_vector);
|
||
}
|
||
|
||
|
||
void
|
||
rpc_mgmt_inq_princ_name (
|
||
RPC_BINDING_HANDLE binding,
|
||
unsigned32 authn_svc,
|
||
unsigned32 princ_name_size,
|
||
unsigned char server_princ_name[],
|
||
error_status_t * status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the management code corresponding to the
|
||
rpc_mgmt_inq_server_princ_name remote operation.
|
||
|
||
--*/
|
||
{
|
||
unsigned char * ServerPrincName;
|
||
|
||
//
|
||
// We have to call the function, even if princ_name_size == 0.
|
||
// The call may be using it just to see if it has access
|
||
//
|
||
|
||
//
|
||
// If the auth fn returns false, the op is denied.
|
||
//
|
||
if ( (*MgmtAuthorizationFn)(binding, RPC_C_MGMT_INQ_PRINC_NAME, status)
|
||
== 0 )
|
||
{
|
||
if (0 == *status || RPC_S_OK == *status)
|
||
{
|
||
*status = RPC_S_ACCESS_DENIED;
|
||
}
|
||
|
||
if (princ_name_size)
|
||
{
|
||
*server_princ_name = '\0';
|
||
}
|
||
return;
|
||
}
|
||
|
||
*status = RpcMgmtInqServerPrincNameA(0, authn_svc, &ServerPrincName);
|
||
if ( *status == 0 )
|
||
{
|
||
unsigned int count;
|
||
if (princ_name_size)
|
||
{
|
||
count = strlen(ServerPrincName);
|
||
if (count > princ_name_size - 1)
|
||
{
|
||
*status = RPC_S_BUFFER_TOO_SMALL;
|
||
}
|
||
else
|
||
{
|
||
RpcpMemoryCopy(server_princ_name, ServerPrincName, count + 1);
|
||
}
|
||
RpcStringFreeA(&ServerPrincName);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (princ_name_size)
|
||
{
|
||
*server_princ_name = '\0';
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
rpc_mgmt_inq_stats (
|
||
RPC_BINDING_HANDLE binding,
|
||
unsigned32 * count,
|
||
unsigned32 statistics[],
|
||
error_status_t * status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the management code corresponding to the rpc_mgmt_inq_stats
|
||
remote operation.
|
||
|
||
--*/
|
||
{
|
||
RPC_STATS_VECTOR __RPC_FAR * StatsVector;
|
||
unsigned long Index;
|
||
|
||
//
|
||
// If the auth fn returns false, the op is denied.
|
||
//
|
||
if ( (*MgmtAuthorizationFn)(binding, RPC_C_MGMT_INQ_STATS, status) == 0 )
|
||
{
|
||
if (0 == *status || RPC_S_OK == *status)
|
||
{
|
||
*status = RPC_S_ACCESS_DENIED;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
*status = RpcMgmtInqStats(0, &StatsVector);
|
||
if ( *status == RPC_S_OK )
|
||
{
|
||
for (Index = 0; Index < StatsVector->Count && Index < *count; Index++)
|
||
{
|
||
statistics[Index] = StatsVector->Stats[Index];
|
||
}
|
||
*count = Index;
|
||
RpcMgmtStatsVectorFree(&StatsVector);
|
||
}
|
||
}
|
||
|
||
|
||
unsigned long
|
||
rpc_mgmt_is_server_listening (
|
||
RPC_BINDING_HANDLE binding,
|
||
unsigned long __RPC_FAR * status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the management code corresponding to the
|
||
rpc_mgmt_is_server_listening remote operation.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// If the auth fn returns false, the op is denied.
|
||
//
|
||
if ( (*MgmtAuthorizationFn)(binding, RPC_C_MGMT_IS_SERVER_LISTEN, status)
|
||
== 0 )
|
||
{
|
||
if (0 == *status || RPC_S_OK == *status)
|
||
{
|
||
*status = RPC_S_ACCESS_DENIED;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
*status = RpcMgmtIsServerListening(0);
|
||
if ( *status == RPC_S_OK )
|
||
{
|
||
return(1);
|
||
}
|
||
|
||
if ( *status == RPC_S_NOT_LISTENING )
|
||
{
|
||
*status = RPC_S_OK;
|
||
}
|
||
|
||
return(0);
|
||
}
|
||
|
||
|
||
void
|
||
rpc_mgmt_stop_server_listening (
|
||
RPC_BINDING_HANDLE binding,
|
||
unsigned long __RPC_FAR * status
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the management code corresponding to the
|
||
rpc_mgmt_stop_server_listening remote operation.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// If the auth fn returns false, the op is denied.
|
||
//
|
||
if ( (*MgmtAuthorizationFn)(binding, RPC_C_MGMT_STOP_SERVER_LISTEN, status)
|
||
== 0 )
|
||
{
|
||
if (0 == *status || RPC_S_OK == *status)
|
||
{
|
||
*status = RPC_S_ACCESS_DENIED;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
// N.B. RpcMgmtStopServerListening just flags the global
|
||
// server as not listening. There is no danger of deadlock
|
||
|
||
*status = RpcMgmtStopServerListening(0);
|
||
}
|
||
|