From 5d1cb8e79edea9e8581d3c2c9dd297310cd9a98c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Mar 2005 23:26:33 +0000 Subject: r6014: rather large change set.... pulling back all recent rpc changes from trunk into 3.0. I've tested a compile and so don't think I've missed any files. But if so, just mail me and I'll clean backup in a couple of hours. Changes include \winreg, \eventlog, \svcctl, and general parse_misc.c updates. I am planning on bracketing the event code with an #ifdef ENABLE_EVENTLOG until I finish merging Marcin's changes (very soon). (This used to be commit 4e0ac63c36527cd8c52ef720cae17e84f67e7221) --- source3/rpc_server/srv_svcctl_nt.c | 291 +++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 source3/rpc_server/srv_svcctl_nt.c (limited to 'source3/rpc_server/srv_svcctl_nt.c') diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c new file mode 100644 index 0000000000..19244d2208 --- /dev/null +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -0,0 +1,291 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald (Jerry) Carter 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/* + * sertup the \PIPE\svcctl db API + */ + +static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */ + +#define SCVCTL_DATABASE_VERSION_V1 1 + +/******************************************************************** +********************************************************************/ + +static BOOL init_svcctl_db( void ) +{ + static pid_t local_pid; + const char *vstring = "INFO/version"; + + /* see if we've already opened the tdb */ + + if (svcctl_tdb && local_pid == sys_getpid()) + return True; + + /* so open it */ + if ( !(svcctl_tdb = tdb_open_log(lock_path("svcctl.tdb"), 0, TDB_DEFAULT, + O_RDWR|O_CREAT, 0600))) + { + DEBUG(0,("Failed to open svcctl database %s (%s)\n", + lock_path("svcctl.tdb"), strerror(errno) )); + return False; + } + + local_pid = sys_getpid(); + + /***** BEGIN Check the tdb version ******/ + + tdb_lock_bystring(svcctl_tdb, vstring, 0); + + if ( tdb_fetch_int32(svcctl_tdb, vstring) != SCVCTL_DATABASE_VERSION_V1 ) + tdb_store_int32(svcctl_tdb, vstring, SCVCTL_DATABASE_VERSION_V1); + + tdb_unlock_bystring(svcctl_tdb, vstring); + + /***** END Check the tdb version ******/ + + return True; +} + +/******************************************************************** + TODO + (a) get and set security descriptors on services + (b) read and write QUERY_SERVICE_CONFIG structures + (c) create default secdesc objects for services and SCM + (d) check access control masks with se_access_check() + (e) implement SERVICE * for associating with open handles +********************************************************************/ + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u) +{ + /* just fake it for now */ + + if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) ) + return WERR_ACCESS_DENIED; + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u) +{ + fstring service; + + rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); + + /* can only be called on service name (not displayname) */ + + if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) ) + return WERR_NO_SUCH_SERVICE; + + if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) ) + return WERR_ACCESS_DENIED; + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u) +{ + if ( !close_policy_hnd( p, &q_u->handle ) ) + return WERR_BADFID; + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u) +{ + fstring service; + fstring displayname; + + rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); + + DEBUG(10,("_svcctl_get_display_name: service name [%s]\n", service)); + + if ( !strequal( service, "NETLOGON" ) ) + return WERR_ACCESS_DENIED; + + fstrcpy( displayname, "Net Logon"); + init_svcctl_r_get_display_name( r_u, displayname ); + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u) +{ + + r_u->svc_status.type = 0x0110; + r_u->svc_status.state = 0x0004; + r_u->svc_status.controls_accepted = 0x0005; + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u) +{ + ENUM_SERVICES_STATUS *services = NULL; + uint32 num_services = 0; + int i = 0; + size_t buffer_size; + WERROR result = WERR_OK; + + /* num_services = str_list_count( lp_enable_svcctl() ); */ + num_services = 2; + + if ( !(services = TALLOC_ARRAY( p->mem_ctx, ENUM_SERVICES_STATUS, num_services )) ) + return WERR_NOMEM; + + DEBUG(8,("_svcctl_enum_services_status: Enumerating %d services\n", num_services)); + + init_unistr( &services[i].servicename, "Spooler" ); + init_unistr( &services[i].displayname, "Spooler" ); + + services[i].status.type = 0x110; + services[i].status.controls_accepted = 0x0; + services[i].status.win32_exit_code = 0x0; + services[i].status.service_exit_code = 0x0; + services[i].status.check_point = 0x0; + services[i].status.wait_hint = 0x0; + if ( !lp_disable_spoolss() ) + services[i].status.state = SVCCTL_RUNNING; + else + services[i].status.state = SVCCTL_STOPPED; + + i++; + + init_unistr( &services[i].servicename, "Netlogon" ); + init_unistr( &services[i].displayname, "Net Logon" ); + + services[i].status.type = 0x20; + services[i].status.controls_accepted = 0x0; + services[i].status.win32_exit_code = 0x0; + services[i].status.service_exit_code = 0x0; + services[i].status.check_point = 0x0; + services[i].status.wait_hint = 0x0; + if ( lp_servicenumber("NETLOGON") != -1 ) + services[i].status.state = SVCCTL_RUNNING; + else + services[i].status.state = SVCCTL_STOPPED; + + buffer_size = 0; + for (i=0; i q_u->buffer_size ) { + num_services = 0; + result = WERR_MORE_DATA; + } + + /* we have to set the outgoing buffer size to the same as the + incoming buffer size (even in the case of failure */ + + rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); + + if ( W_ERROR_IS_OK(result) ) { + for ( i=0; ibuffer, 0 ); + } + + r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; + r_u->returned = num_services; + + if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) ) + return WERR_NOMEM; + + *r_u->resume = 0x0; + + return result; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u) +{ + return WERR_ACCESS_DENIED; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u) +{ + return WERR_ACCESS_DENIED; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u ) +{ + + /* we have to set the outgoing buffer size to the same as the + incoming buffer size (even in the case of failure */ + + rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); + + r_u->needed = q_u->buffer_size; + + /* no dependent services...basically a stub function */ + r_u->returned = 0; + + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u ) +{ + + /* we have to set the outgoing buffer size to the same as the + incoming buffer size (even in the case of failure */ + + r_u->needed = q_u->buffer_size; + + /* no dependent services...basically a stub function */ + + return WERR_ACCESS_DENIED; +} + + -- cgit