/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Service Control Services (SVCCTL) RPC interface definition.
* This interface provides remote access to list SMF services
* from a Windows client.
*
* SVCCTL access is restricted to administrators: members of the
* Domain Admins or Administrators groups.
*/
#include <stdio.h>
#include <strings.h>
#include <smbsrv/libntsvcs.h>
#define SVCCTL_OPENSVC_OP_UNIMPLEMENTED(S) \
((S) & SERVICE_CHANGE_CONFIG) || \
((S) & SERVICE_PAUSE_CONTINUE) || \
((S) & SERVICE_START) || \
((S) & SERVICE_STOP) || \
((S) & SERVICE_ENUMERATE_DEPENDENTS)
typedef union {
static int svcctl_s_Close(void *, ndr_xa_t *);
static int svcctl_s_ControlService(void *, ndr_xa_t *);
static int svcctl_s_DeleteService(void *, ndr_xa_t *);
static int svcctl_s_QueryServiceSecurity(void *, ndr_xa_t *);
static int svcctl_s_SetServiceSecurity(void *, ndr_xa_t *);
static int svcctl_s_OpenManager(void *, ndr_xa_t *);
static int svcctl_s_OpenService(void *, ndr_xa_t *);
static int svcctl_s_QueryServiceStatus(void *, ndr_xa_t *);
static int svcctl_s_QueryServiceConfig(void *, ndr_xa_t *);
static int svcctl_s_StartService(void *, ndr_xa_t *);
static int svcctl_s_EnumDependentServices(void *, ndr_xa_t *);
static int svcctl_s_EnumServicesStatus(void *, ndr_xa_t *);
static int svcctl_s_GetServiceDisplayNameW(void *, ndr_xa_t *);
static int svcctl_s_GetServiceKeyNameW(void *, ndr_xa_t *);
static int svcctl_s_OpenSCManagerA(void *, ndr_xa_t *);
static int svcctl_s_OpenServiceA(void *, ndr_xa_t *);
static int svcctl_s_EnumServicesStatusA(void *, ndr_xa_t *);
static int svcctl_s_QueryServiceConfig2W(void *, ndr_xa_t *);
static int svcctl_s_QueryServiceStatusEx(void *, ndr_xa_t *);
{0}
};
"SVCCTL", /* name */
"Service Control Services", /* desc */
"\\svcctl", /* endpoint */
PIPE_NTSVCS, /* sec_addr_port */
"367abb81-9844-35f1-ad32-98f038001003", 2, /* abstract */
0, /* no bind_instance_size */
0, /* no bind_req() */
0, /* no unbind_and_close() */
0, /* use generic_call_stub() */
svcctl_stub_table /* stub_table */
};
/*
* svcctl_initialize
*
* This function registers the SVCCTL RPC interface with the RPC runtime
* library. It must be called in order to use either the client side
* or the server side functions.
*/
void
svcctl_initialize(void)
{
(void) ndr_svc_register(&svcctl_service);
svcctl_init();
}
void
svcctl_finalize(void)
{
svcctl_fini();
}
/*
* svcctl_hdlookup
*
*/
static ndr_handle_t *
{
return (NULL);
return (NULL);
return (NULL);
return (hd);
}
/*
* svcctl_hdfree
*
*/
static void
{
case SVCCTL_MANAGER_CONTEXT:
break;
case SVCCTL_SERVICE_CONTEXT:
break;
default:
break;
}
}
}
/*
* svcctl_mgr_hdalloc
*
* Handle allocation wrapper to setup the local manager context.
*/
static ndr_hdid_t *
{
return (NULL);
return (NULL);
}
if (svcctl_scm_scf_handle_init(mgr_ctx) < 0) {
return (NULL);
}
if (svcctl_scm_init(mgr_ctx) < 0) {
return (NULL);
}
}
/*
* svcctl_get_mgr_ctx
*
* This function looks up a reference to local manager context.
*/
static svcctl_manager_context_t *
{
return (NULL);
return (mgr_ctx);
}
/*
* svcctl_svc_hdalloc
*
* Handle allocation wrapper to setup the local service context.
*/
static ndr_hdid_t *
{
int max_name_sz = 0;
char *svcname;
return (NULL);
return (NULL);
}
return (NULL);
}
return (NULL);
}
}
/*
* svcctl_s_Close
*
* This is a request to close the SVCCTL interface specified by the
* handle. Free the handle and zero out the result handle for the
* client.
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
*/
static int
{
return (NDR_DRC_OK);
}
/*
* svcctl_s_ControlService
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_CONTINUE:
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_DeleteService
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_QueryServiceSecurity
*/
static int
{
}
if (sec_info == 0) {
}
}
}
param->bytes_needed = 0;
return (NDR_DRC_OK);
return (NDR_DRC_OK);
}
/*
* svcctl_s_SetServiceSecurity
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_OpenManager
*
* Request to open the service control manager.
* The caller must have administrator rights in order to open this
* interface. We don't support write (SC_MANAGER_LOCK) access.
*
* Returns:
* ERROR_SUCCESS
* ERROR_ACCESS_DENIED
*
* On success, returns a handle for use with subsequent svcctl requests.
*/
static int
{
int rc;
return (NDR_DRC_OK);
}
if (id) {
} else {
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_OpenService
*
* Return a handle for use with subsequent svcctl requests.
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
* ERROR_SERVICE_DOES_NOT_EXIST
* ERROR_CALL_NOT_IMPLEMENTED
*/
static int
{
/* Allow service handle allocations for only status & config queries */
if (unimplemented_operations) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
if (id) {
} else {
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_QueryServiceStatus
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_EnumDependentServices
*
* Enumerate the list of services that depend on the specified service.
*/
static int
{
int input_bufsize = 0;
}
}
}
case SERVICE_STOPPED:
case SERVICE_START_PENDING:
case SERVICE_STOP_PENDING:
case SERVICE_RUNNING:
case SERVICE_CONTINUE_PENDING:
case SERVICE_PAUSE_PENDING:
case SERVICE_PAUSED:
break;
default:
}
return (NDR_DRC_OK);
}
}
param->bytes_needed = 0;
return (NDR_DRC_OK);
return (NDR_DRC_OK);
}
/*
* svcctl_s_EnumServicesStatus
*
* Enumerate the list of services we support.
*/
static int
{
}
if (svcctl_scm_refresh(mgr_ctx) != 0) {
}
}
if (buf_size < SVCCTL_ENUMSERVICES_MINBUFSIZE) {
if (param->resume_handle)
*param->resume_handle = 0;
return (NDR_DRC_OK);
}
if (resume_handle != 0) {
} else {
if (param->resume_handle)
*param->resume_handle = 0;
param->bytes_needed = 0;
}
return (NDR_DRC_OK);
return (NDR_DRC_OK);
}
/*
* svcctl_s_QueryServiceConfig
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
*/
static int
{
int bytes_needed = 0;
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
bytes_needed = sizeof (svc_config_t);
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_StartService
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
else
return (NDR_DRC_OK);
}
/*
* svcctl_s_GetServiceDisplayNameW
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
* ERROR_SERVICE_DOES_NOT_EXIST
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_GetServiceKeyNameW
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
* ERROR_SERVICE_DOES_NOT_EXIST
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_OpenSCManagerA
*
* Request to open the service control manager.
* The caller must have administrator rights in order to open this
* interface. We don't support write (SC_MANAGER_LOCK) access.
*
* Returns:
* ERROR_SUCCESS
* ERROR_ACCESS_DENIED
*
* On success, returns a handle for use with subsequent svcctl requests.
*/
static int
{
int rc;
return (NDR_DRC_OK);
}
if (id) {
} else {
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_OpenServiceA
*
* Return a handle for use with subsequent svcctl requests.
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
* ERROR_SERVICE_DOES_NOT_EXIST
* ERROR_CALL_NOT_IMPLEMENTED
*/
static int
{
/* Allow service handle allocations for only status & config queries */
if (unimplemented_operations) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
if (id) {
} else {
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_EnumServicesStatusA
*
* Enumerate the list of services we support as ASCII.
*/
static int
{
}
if (svcctl_scm_refresh(mgr_ctx) != 0) {
}
}
if (resume_handle != 0) {
} else {
if (param->resume_handle)
*param->resume_handle = 0;
param->bytes_needed = 0;
}
return (NDR_DRC_OK);
return (NDR_DRC_OK);
}
/*
* svcctl_s_QueryServiceConfig2W
*
* Returns:
* ERROR_SUCCESS
* ERROR_INVALID_HANDLE
* ERROR_INVALID_LEVEL
* ERROR_NOT_ENOUGH_MEMORY
*/
static int
{
char *desc;
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
switch (param->info_level) {
break;
}
break;
}
if (input_bufsize <= bytes_needed) {
return (NDR_DRC_OK);
}
offset = sizeof (svc_description_t);
/*LINTED E_BAD_PTR_CAST_ALIGN*/
break;
bytes_needed = sizeof (svc_failure_actions_t);
if (input_bufsize <= bytes_needed) {
return (NDR_DRC_OK);
}
break;
break;
break;
default:
break;
}
if (status != ERROR_SUCCESS) {
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* svcctl_s_QueryServiceStatusEx
*/
static int
{
}
}
}
bytes_needed = sizeof (svc_status_ex_t);
return (NDR_DRC_OK);
}
}
}
svc_status_ex->ctrl_accepted = 0;
svc_status_ex->w32_exitcode = 0;
svc_status_ex->check_point = 0;
svc_status_ex->wait_hint = 0;
return (NDR_DRC_OK);
return (NDR_DRC_OK);
}