/*++ Copyright (c) 1993 Microsoft Corporation 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 #include #include 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, unsigned long authn_svc, unsigned long princ_name_size, unsigned char __RPC_FAR * server_princ_name, unsigned long __RPC_FAR * status ) /*++ Routine Description: This is the management code corresponding to the rpc_mgmt_inq_server_princ_name remote operation. --*/ { unsigned char * ServerPrincName; // // 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; } *server_princ_name = '\0'; return; } *status = RpcMgmtInqServerPrincNameA(0, authn_svc, &ServerPrincName); if ( *status == 0 ) { unsigned int count; count = strlen(ServerPrincName); if (count > princ_name_size - 1) { *status = RPC_S_BUFFER_TOO_SMALL; } else { RpcpMemoryCopy(server_princ_name, ServerPrincName, count + 1); } RpcStringFree(&ServerPrincName); } else { *server_princ_name = '\0'; } } void rpc_mgmt_inq_stats ( RPC_BINDING_HANDLE binding, unsigned long __RPC_FAR * count, unsigned long __RPC_FAR * statistics, unsigned long __RPC_FAR * 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 < *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; } // BUGBUG: What if StopServerListening won't return until // this call completes? *status = RpcMgmtStopServerListening(0); }