diff options
-rw-r--r-- | source3/include/rpc_svcctl.h | 25 | ||||
-rw-r--r-- | source3/rpc_server/srv_svcctl_nt.c | 716 |
2 files changed, 323 insertions, 418 deletions
diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index b344804bcf..c49d536e49 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -106,8 +106,8 @@ #define SVCCTL_CONTROL_CONTINUE 0x00000003 #define SVCCTL_CONTROL_SHUTDOWN 0x00000004 -#define SVC_HANDLE_IS_SCM 0x0000001 -#define SVC_HANDLE_IS_SERVICE 0x0000002 +#define SVC_HANDLE_IS_SCM 0x0000001 +#define SVC_HANDLE_IS_SERVICE 0x0000002 #define SVC_STATUS_PROCESS_INFO 0x00000001 @@ -196,6 +196,27 @@ typedef struct Service_info_struct { pstring description; } Service_info; +/* + * dispatch table of functions to handle the =ServiceControl API + */ + +typedef struct { + /* functions for enumerating subkeys and values */ + WERROR (*stop_service)( void ); + WERROR (*start_service) ( void ); + BOOL (*service_status)( SERVICE_STATUS *status ); +} SERVICE_CONTROL_OPS; + +/* structure to store the service handle information */ + +typedef struct _ServiceInfo { + uint8 type; + char *name; + uint32 access_granted; + SERVICE_CONTROL_OPS *ops; +} SERVICE_INFO; + + /* rpc structures */ /**************************/ diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index 1feb0f66e4..707fd8bdd5 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -1,7 +1,8 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Copyright (C) Gerald (Jerry) Carter 2005 + * Copyright (C) Gerald (Jerry) Carter 2005, + * Copyright (C) Marcin Krzysztof Porwit 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 @@ -90,8 +91,99 @@ static const Internal_service_description ISD[] = { (d) check access control masks with se_access_check() ********************************************************************/ -/* parse a LSB init.d type file for things it provides, dependencies, descriptions, etc. */ - +/********************************************************************* + given a service nice name, find the underlying service name +*********************************************************************/ + +BOOL _svcctl_service_nicename_to_servicename(TDB_CONTEXT *stdb,pstring service_nicename, pstring servicename,int szsvcname) +{ + pstring keystring; + TDB_DATA key_data; + + if ((stdb == NULL) || (service_nicename==NULL) || (servicename == NULL)) + return False; + + pstr_sprintf(keystring,"SERVICE_NICENAME/%s", servicename); + + DEBUG(5, ("_svcctl_service_nicename_to_servicename: Looking for service name [%s], key [%s]\n", + service_nicename, keystring)); + + key_data = tdb_fetch_bystring(stdb,keystring); + + if (key_data.dsize == 0) { + DEBUG(5, ("_svcctl_service_nicename_to_servicename: [%s] Not found, tried key [%s]\n",service_nicename,keystring)); + return False; + } + + strncpy(servicename,key_data.dptr,szsvcname); + servicename[(key_data.dsize > szsvcname ? szsvcname : key_data.dsize)] = 0; + DEBUG(5, ("_svcctl_service_nicename_to_servicename: Found service name [%s], name is [%s]\n", + service_nicename,servicename)); + + return True; +} + +/********************************************************************* +*********************************************************************/ + +static BOOL write_si_to_service_tdb(TDB_CONTEXT *stdb,char *service_name, Service_info *si) +{ + pstring keystring; + + /* Note -- when we write to the tdb, we "index" on the filename + field, not the nice name. when a service is "opened", it is + opened by the nice (SERVICENAME) name, not the file name. + So there needs to be a mapping from nice name back to the file name. */ + + if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0)) + return False; + + + /* Store the nicename */ + + pstr_sprintf(keystring,"SERVICE_NICENAME/%s", si->servicename); + tdb_store_bystring(stdb,keystring,string_tdb_data(service_name),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicetype),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->filename),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->provides),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/SERVICENAME", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicename),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->dependencies),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstart),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTOP", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstop),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstart),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstop),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name); + tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE); + + pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name); + tdb_lock_bystring(stdb, keystring, 0); + if (si->shortdescription && *si->shortdescription) + tdb_store_bystring(stdb,keystring,string_tdb_data(si->shortdescription),TDB_REPLACE); + else + tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE); + + return True; +} + /******************************************************************************* Get the INTERNAL services information for the given service name. @@ -100,6 +192,7 @@ static const Internal_service_description ISD[] = { static BOOL _svcctl_get_internal_service_data(const Internal_service_description *isd, Service_info *si) { ZERO_STRUCTP( si ); +#if 0 pstrcpy( si->servicename, isd->displayname); pstrcpy( si->servicetype, "INTERNAL"); @@ -107,6 +200,7 @@ static BOOL _svcctl_get_internal_service_data(const Internal_service_description pstrcpy( si->provides, isd->displayname); pstrcpy( si->description, isd->description); pstrcpy( si->shortdescription, isd->description); +#endif return True; } @@ -257,172 +351,6 @@ static BOOL _svcctl_get_LSB_data(char *fname,Service_info *si ) return False; } - -BOOL _svcctl_read_service_tdb_to_si(TDB_CONTEXT *stdb,char *service_name, Service_info *si) -{ - - pstring keystring; - TDB_DATA key_data; - - if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0)) - return False; - - /* TODO - error handling -- what if the service isn't in the DB? */ - - pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->servicetype,key_data.dptr,key_data.dsize); - si->servicetype[key_data.dsize] = 0; - - /* crude check to see if the service exists... */ - DEBUG(3,("Size of the TYPE field is %d\n",key_data.dsize)); - if (key_data.dsize == 0) - return False; - - pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->filename,key_data.dptr,key_data.dsize); - si->filename[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->provides,key_data.dptr,key_data.dsize); - si->provides[key_data.dsize] = 0; - strncpy(si->servicename,key_data.dptr,key_data.dsize); - si->servicename[key_data.dsize] = 0; - - - pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->dependencies,key_data.dptr,key_data.dsize); - si->dependencies[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->shouldstart,key_data.dptr,key_data.dsize); - si->shouldstart[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/SHOULD_STOP", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->shouldstop,key_data.dptr,key_data.dsize); - si->shouldstop[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->requiredstart,key_data.dptr,key_data.dsize); - si->requiredstart[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->requiredstop,key_data.dptr,key_data.dsize); - si->requiredstop[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->description,key_data.dptr,key_data.dsize); - si->description[key_data.dsize] = 0; - - pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name); - key_data = tdb_fetch_bystring(stdb,keystring); - strncpy(si->shortdescription,key_data.dptr,key_data.dsize); - si->shortdescription[key_data.dsize] = 0; - - return True; -} - -/********************************************************************* - given a service nice name, find the underlying service name -*********************************************************************/ - -BOOL _svcctl_service_nicename_to_servicename(TDB_CONTEXT *stdb,pstring service_nicename, pstring servicename,int szsvcname) -{ - pstring keystring; - TDB_DATA key_data; - - if ((stdb == NULL) || (service_nicename==NULL) || (servicename == NULL)) - return False; - - pstr_sprintf(keystring,"SERVICE_NICENAME/%s", servicename); - - DEBUG(5, ("_svcctl_service_nicename_to_servicename: Looking for service name [%s], key [%s]\n", - service_nicename, keystring)); - - key_data = tdb_fetch_bystring(stdb,keystring); - - if (key_data.dsize == 0) { - DEBUG(5, ("_svcctl_service_nicename_to_servicename: [%s] Not found, tried key [%s]\n",service_nicename,keystring)); - return False; - } - - strncpy(servicename,key_data.dptr,szsvcname); - servicename[(key_data.dsize > szsvcname ? szsvcname : key_data.dsize)] = 0; - DEBUG(5, ("_svcctl_service_nicename_to_servicename: Found service name [%s], name is [%s]\n", - service_nicename,servicename)); - - return True; -} - -/********************************************************************* -*********************************************************************/ - -BOOL _svcctl_write_si_to_service_tdb(TDB_CONTEXT *stdb,char *service_name, Service_info *si) -{ - pstring keystring; - - /* Note -- when we write to the tdb, we "index" on the filename - field, not the nice name. when a service is "opened", it is - opened by the nice (SERVICENAME) name, not the file name. - So there needs to be a mapping from nice name back to the file name. */ - - if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0)) - return False; - - - /* Store the nicename */ - - pstr_sprintf(keystring,"SERVICE_NICENAME/%s", si->servicename); - tdb_store_bystring(stdb,keystring,string_tdb_data(service_name),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicetype),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->filename),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->provides),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/SERVICENAME", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicename),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->dependencies),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstart),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTOP", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstop),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstart),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstop),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name); - tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE); - - pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name); - tdb_lock_bystring(stdb, keystring, 0); - if (si->shortdescription && *si->shortdescription) - tdb_store_bystring(stdb,keystring,string_tdb_data(si->shortdescription),TDB_REPLACE); - else - tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE); - - return True; -} - /**************************************************************************** Create/Open the service control manager tdb. This code a clone of init_group_mapping. ****************************************************************************/ @@ -471,7 +399,7 @@ BOOL init_svcctl_db(void) DEBUG(10,("Reading information on service %s\n",*svcname)); if (_svcctl_get_LSB_data(*svcname,&si));{ /* write the information to the TDB */ - _svcctl_write_si_to_service_tdb(service_tdb,*svcname,&si); + write_si_to_service_tdb(service_tdb,*svcname,&si); /* definitely not efficient to do it this way. */ pstrcat(external_service_list,"\""); pstrcat(external_service_list,*svcname); @@ -494,7 +422,7 @@ BOOL init_svcctl_db(void) DEBUG(10,("Reading information on service %s\n",isd_ptr->filename)); if (_svcctl_get_internal_service_data(isd_ptr,&si)){ /* write the information to the TDB */ - _svcctl_write_si_to_service_tdb(service_tdb,(char *)isd_ptr->filename,&si); + write_si_to_service_tdb(service_tdb,(char *)isd_ptr->filename,&si); /* definitely not efficient to do it this way. */ pstrcat(internal_service_list,"\""); pstrcat(internal_service_list,isd_ptr->filename); @@ -512,100 +440,161 @@ BOOL init_svcctl_db(void) return True; } -/* Service_info related functions */ -static Service_info *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *handle) +/******************************************************************** +********************************************************************/ + +static BOOL read_service_tdb_to_si(TDB_CONTEXT *stdb,char *service_name, Service_info *si) { - Service_info *info = NULL; - if(!(find_policy_by_hnd(p,handle,(void **)&info))) - DEBUG(2,("find_service_info_by_hnd: service not found.\n")); + pstring keystring; + TDB_DATA key_data; - return info; -} + if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0)) + return False; -static void free_service_info(void *ptr) -{ - Service_info *info = (Service_info *)ptr; - memset(info,'0',sizeof(Service_info)); - SAFE_FREE(info); -} + /* TODO - error handling -- what if the service isn't in the DB? */ + + pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->servicetype,key_data.dptr,key_data.dsize); + si->servicetype[key_data.dsize] = 0; -/* SCM_info related functions */ -static void free_SCM_info(void *ptr) -{ - SCM_info *info = (SCM_info *)ptr; - memset(info->target_server_name, '0', sizeof(*(info->target_server_name))); - memset(info->target_db_name, '0', sizeof(*(info->target_db_name))); - memset(info, 0, sizeof(*(info))); - SAFE_FREE(info); -} + /* crude check to see if the service exists... */ + DEBUG(3,("Size of the TYPE field is %d\n",key_data.dsize)); + if (key_data.dsize == 0) + return False; -static SCM_info *find_SCManager_info_by_hnd(pipes_struct *p, POLICY_HND *handle) -{ - SCM_info *info = NULL; - - if ( !(find_policy_by_hnd(p,handle,(void **)&info)) ) - DEBUG(2,("svcctl_find_SCManager_info_by_hnd: service not found.\n")); + pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->filename,key_data.dptr,key_data.dsize); + si->filename[key_data.dsize] = 0; - return info; -} + pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->provides,key_data.dptr,key_data.dsize); + si->provides[key_data.dsize] = 0; + strncpy(si->servicename,key_data.dptr,key_data.dsize); + si->servicename[key_data.dsize] = 0; -static BOOL _svcctl_open_SCManager_hook(SCM_info *info) -{ - return True; -} + + pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->dependencies,key_data.dptr,key_data.dsize); + si->dependencies[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->shouldstart,key_data.dptr,key_data.dsize); + si->shouldstart[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/SHOULD_STOP", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->shouldstop,key_data.dptr,key_data.dsize); + si->shouldstop[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->requiredstart,key_data.dptr,key_data.dsize); + si->requiredstart[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->requiredstop,key_data.dptr,key_data.dsize); + si->requiredstop[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->description,key_data.dptr,key_data.dsize); + si->description[key_data.dsize] = 0; + + pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name); + key_data = tdb_fetch_bystring(stdb,keystring); + strncpy(si->shortdescription,key_data.dptr,key_data.dsize); + si->shortdescription[key_data.dsize] = 0; -static BOOL _svcctl_close_SCManager_hook(SCM_info *info) -{ return True; } -/******************************************************************** -********************************************************************/ - -WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u) +/****************************************************************** + free() function for REGISTRY_KEY + *****************************************************************/ + +static void free_service_handle_info(void *ptr) { - /* create the DB of the services that we have */ + SERVICE_INFO *info = (SERVICE_INFO*)ptr; - /* associate the information from the service opened in the create_policy_hnd string */ - - SCM_info *info = NULL; - fstring fhandle_string; + SAFE_FREE(info->name); + SAFE_FREE(info); +} - if(!q_u || !r_u) - return WERR_NOMEM; - - if((info = SMB_MALLOC_P(SCM_info)) == NULL) - return WERR_NOMEM; - - ZERO_STRUCTP(info); +/****************************************************************** + Find a registry key handle and return a SERVICE_INFO + *****************************************************************/ - info->type = SVC_HANDLE_IS_SCM; +static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd) +{ + SERVICE_INFO *service_info = NULL; - if(q_u->servername != 0) - unistr2_to_ascii(info->target_server_name, q_u->servername, sizeof(info->target_server_name)); - else { - /* if servername == NULL, use the local computer */ - pstrcpy(info->target_server_name, global_myname()); + if( !find_policy_by_hnd( p, hnd, (void **)&service_info) ) { + DEBUG(2,("find_service_info_by_hnd: handle not found")); + return NULL; } - DEBUG(10, ("_svcctl_open_scmanager: Using [%s] as the server name.\n", info->target_server_name)); - if(q_u->database != 0) - unistr2_to_ascii(info->target_db_name, q_u->database, sizeof(info->target_db_name)); - else - pstrcpy(info->target_db_name, "ServicesActive"); + return service_info; +} - if(!create_policy_hnd(p, &(r_u->handle), free_SCM_info, (void *)info)) +/****************************************************************** + *****************************************************************/ + +WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, const char *service ) +{ + SERVICE_INFO *info = NULL; + + if ( !(info = SMB_MALLOC_P( SERVICE_INFO )) ) return WERR_NOMEM; + + /* the Service Manager has a NULL name */ + + if ( !service ) { + info->type = SVC_HANDLE_IS_SCM; + } else { + info->type = SVC_HANDLE_IS_SERVICE; + + if ( !(info->name = SMB_STRDUP( service )) ) { + free_service_handle_info( info ); + WERR_NOMEM; + } + +#if 0 + /* lookup the SERVICE_CONTROL_OPS */ - policy_handle_to_string(&r_u->handle, &fhandle_string); - DEBUG(10, ("_svcctl_open_scmanager: Opening [%s] as the target services db, handle [%s]\n", info->target_db_name,fhandle_string)); + for ( i=0; svcctl_ops[i].name; i++ ) { + ;; + } +#endif + } - if(!(_svcctl_open_SCManager_hook(info))) { - /* TODO - should we free the memory that may have been allocated with the policy handle? */ - return WERR_BADFILE; + /* store the SERVICE_INFO and create an open handle */ + + if ( !create_policy_hnd( p, handle, free_service_handle_info, info ) ) { + free_service_handle_info( info ); + return WERR_ACCESS_DENIED; } + return WERR_OK; +} + +/******************************************************************** +********************************************************************/ + +WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u) +{ + /* perform access checks */ + + + /* open the handle and return */ + + return create_open_service_handle( p, &r_u->handle, NULL ); } @@ -615,116 +604,35 @@ WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVC WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u) { pstring service; - pstring service_filename; - fstring fhandle_string; - Service_info *info; - - if(!q_u || !r_u) - return WERR_NOMEM; - - if((info = SMB_MALLOC_P(Service_info)) == NULL) - return WERR_NOMEM; - - ZERO_STRUCTP(info); - - info->type = SVC_HANDLE_IS_SERVICE; rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); - if (service_tdb == NULL) { - DEBUG(1, ("_svcctl_open_service: Cannot open Service [%s], the service database is not open; handle [%s]\n", service,fhandle_string)); - return WERR_ACCESS_DENIED; + DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service)); + + if ( !service_tdb ) { + DEBUG(1, ("_svcctl_open_service: service database is not open\n!")); + return WERR_ACCESS_DENIED; } - DEBUG(1, ("_svcctl_open_service: Attempting to open Service [%s], \n", service)); + + /* check the access granted on the SCM handle */ + + /* check the access requested on this service */ + -#if 0 - if ( !_svcctl_service_nicename_to_servicename(service_tdb, service, service_filename, sizeof(pstring)) ) { - DEBUG(1, ("_svcctl_open_service: Cannot open Service [%s], the service can't be found\n", service)); +#if 0 /* FIXME!!! */ + if ( ! read_service_tdb_to_si(service_tdb,service, info) ) { return WERR_NO_SUCH_SERVICE; - } -#else - pstrcpy(service_filename,service); #endif - - if (_svcctl_read_service_tdb_to_si(service_tdb,service, info)) - DEBUG(1, ("_svcctl_open_service: Found service [%s], servicename [%s], \n", service, info->servicename)); - else - return WERR_NO_SUCH_SERVICE; -#if 0 - if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) ) - return WERR_NO_SUCH_SERVICE; -#endif - if ( !create_policy_hnd( p, &(r_u->handle), free_service_info, (void *)info ) ) - return WERR_ACCESS_DENIED; - - policy_handle_to_string(&r_u->handle, &fhandle_string); - DEBUG(10, ("_svcctl_open_service: Opening Service [%s], handle [%s]\n", service,fhandle_string)); - - return WERR_OK; + return create_open_service_handle( p, &r_u->handle, service ); } /******************************************************************** ********************************************************************/ -/* Note that this can be called to close an individual service, ** OR ** the Service Control Manager */ - WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u) { - SCM_info *scminfo; - Service_info *svcinfo; - POLICY_HND *handle; - fstring fhandle_string; - POLICY_HND null_policy_handle; - - - handle = &(q_u->handle); - - /* a handle is returned in the close when it's for a service */ - - policy_handle_to_string(handle, &fhandle_string); - DEBUG(10, ("_svcctl_close_service: Closing handle [%s]\n",fhandle_string)); - - ZERO_STRUCT(null_policy_handle); - - policy_handle_to_string(handle, &fhandle_string); - DEBUG(10, ("_svcctl_close_service: Closing handle [%s]\n",fhandle_string)); - - scminfo = find_SCManager_info_by_hnd(p, handle); - - if ((NULL != scminfo) && (scminfo->type == SVC_HANDLE_IS_SCM)) { - DEBUG(3,("_svcctl_close_service: Closing SERVICE DATABASE [%s]\n", scminfo->target_db_name)); - - if(!(_svcctl_close_SCManager_hook(scminfo))) - return WERR_BADFILE; - - if(!(close_policy_hnd(p, handle))) - { - /* WERR_NOMEM is probably not the correct error, but until I figure out a better - one it will have to do */ - DEBUG(3,("_svcctl_close_service: Can't close SCM \n")); - return WERR_NOMEM; - } - memcpy(&(r_u->handle),&null_policy_handle, sizeof(POLICY_HND)); - return WERR_OK; - } - - if ((NULL != scminfo) && (scminfo->type == SVC_HANDLE_IS_SERVICE)) { - svcinfo = (Service_info *)scminfo; - DEBUG(3,("_svcctl_close_service: Handle is a SERVICE not SCM \n")); - DEBUG(3,("_svcctl_close_service: Closing SERVICE [%s]\n", svcinfo->servicename)); - if(!(close_policy_hnd(p, handle))) - { - /* WERR_NOMEM is probably not the correct error, but until I figure out a better - one it will have to do */ - DEBUG(3,("_svcctl_close_service: Can't close SERVICE [%s]\n", svcinfo->servicename)); - return WERR_NOMEM; - } - } - - memcpy(&(r_u->handle),&null_policy_handle, sizeof(POLICY_HND)); - - return WERR_OK; + return close_policy_hnd( p, &q_u->handle ) ? WERR_OK : WERR_BADFID; } /******************************************************************** @@ -734,17 +642,13 @@ WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, { fstring service; fstring displayname; - fstring fhandle_string; - Service_info *service_info; + SERVICE_INFO *service_info; POLICY_HND *handle; rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); handle = &(q_u->handle); - policy_handle_to_string(&q_u->handle, &fhandle_string); - - DEBUG(10, ("_svcctl_get_display_name: Looking for handle [%s]\n",(char *)&fhandle_string)); service_info = find_service_info_by_hnd(p, handle); @@ -753,14 +657,9 @@ WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, return WERR_ACCESS_DENIED; } - DEBUG(10, ("_svcctl_get_display_name: Found service [%s], [%s]\n",service_info->servicename,service_info->filename)); - /* no dependent services...basically a stub function */ + DEBUG(10,("_svcctl_get_display_name: Found service [%s]\n", service_info->name )); -#if 0 - if ( !strequal( service, "NETLOGON" ) ) - return WERR_ACCESS_DENIED; -#endif - fstrcpy( displayname, service_info->servicename) ; + fstrcpy( displayname, "FIX ME!" ); init_svcctl_r_get_display_name( r_u, displayname ); @@ -772,7 +671,6 @@ WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u) { - r_u->svc_status.type = 0x0020; r_u->svc_status.state = 0x0004; r_u->svc_status.controls_accepted = 0x0005; @@ -791,7 +689,7 @@ int _svcctl_num_external_services(void) if (!service_tdb) { - DEBUG(8,("_svcctl_enum_external_services: service database is not open!!!\n")); + DEBUG(8,("enum_external_services: service database is not open!!!\n")); num_services = 0; } else { pstrcpy(keystring,"EXTERNAL_SERVICES"); @@ -801,7 +699,7 @@ int _svcctl_num_external_services(void) if ((key_data.dptr != NULL) && (key_data.dsize != 0)) { strncpy(external_services_string,key_data.dptr,key_data.dsize); external_services_string[key_data.dsize] = 0; - DEBUG(8,("_svcctl_enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize)); + DEBUG(8,("enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize)); } tdb_unlock_bystring(service_tdb, keystring); } @@ -814,23 +712,26 @@ int _svcctl_num_external_services(void) -/* - - Gather information on the "external services". These are services listed in the smb.conf file, and found to exist through - checks in this code. Note that added will be incremented on the basis of the number of services added. svc_ptr should have enough - memory allocated to accommodate all of the services that exist. - - Typically _svcctl_num_external_services is used to "size" the amount of memory allocated, but does little/no work. - - _svcctl_enum_external_services actually examines each of the specified external services, populates the memory structures, and returns. - - ** note that 'added' may end up with less than the number of services found in _num_external_services, such as the case when a service is - called out, but the actual service doesn't exist or the file can't be read for the service information. - - - */ +/******************************************************************** + Gather information on the "external services". These are services + listed in the smb.conf file, and found to exist through checks in + this code. Note that added will be incremented on the basis of the + number of services added. svc_ptr should have enough memory allocated + to accommodate all of the services that exist. + + Typically _svcctl_num_external_services is used to "size" the amount of + memory allocated, but does little/no work. + + enum_external_services() actually examines each of the specified + external services, populates the memory structures, and returns. + + ** note that 'added' may end up with less than the number of services + found in _num_external_services, such as the case when a service is + called out, but the actual service doesn't exist or the file can't be + read for the service information. +********************************************************************/ -WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc_ptr, int existing_services,int *added) +WERROR enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc_ptr, int existing_services,int *added) { /* *svc_ptr must have pre-allocated memory */ int num_services = 0; @@ -846,7 +747,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc *added = num_services; if (!service_tdb) { - DEBUG(8,("_svcctl_enum_external_services: service database is not open!!!\n")); + DEBUG(8,("enum_external_services: service database is not open!!!\n")); } else { pstrcpy(keystring,"EXTERNAL_SERVICES"); tdb_lock_bystring(service_tdb, keystring, 0); @@ -854,7 +755,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc if ((key_data.dptr != NULL) && (key_data.dsize != 0)) { strncpy(external_services_string,key_data.dptr,key_data.dsize); external_services_string[key_data.dsize] = 0; - DEBUG(8,("_svcctl_enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize)); + DEBUG(8,("enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize)); } tdb_unlock_bystring(service_tdb, keystring); } @@ -863,24 +764,24 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc num_services = str_list_count( (const char **)svc_list); if (0 == num_services) { - DEBUG(8,("_svcctl_enum_external_services: there are no external services\n")); + DEBUG(8,("enum_external_services: there are no external services\n")); *added = num_services; return WERR_OK; } - DEBUG(8,("_svcctl_enum_external_services: there are [%d] external services\n",num_services)); + DEBUG(8,("enum_external_services: there are [%d] external services\n",num_services)); si=TALLOC_ARRAY( tcx, Service_info, 1 ); if (si == NULL) { - DEBUG(8,("_svcctl_enum_external_services: Failed to alloc si\n")); + DEBUG(8,("enum_external_services: Failed to alloc si\n")); return WERR_NOMEM; } #if 0 /* *svc_ptr has the pointer to the array if there is one already. NULL if not. */ if ((existing_services>0) && svc_ptr && *svc_ptr) { /* reallocate vs. allocate */ - DEBUG(8,("_svcctl_enum_external_services: REALLOCing %x to %d services\n", *svc_ptr, existing_services+num_services)); + DEBUG(8,("enum_external_services: REALLOCing %x to %d services\n", *svc_ptr, existing_services+num_services)); services=TALLOC_REALLOC_ARRAY(tcx,*svc_ptr,ENUM_SERVICES_STATUS,existing_services+num_services); - DEBUG(8,("_svcctl_enum_external_services: REALLOCed to %x services\n", services)); + DEBUG(8,("enum_external_services: REALLOCed to %x services\n", services)); if (!services) return WERR_NOMEM; *svc_ptr = services; @@ -898,13 +799,13 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc } svcname = svc_list; - DEBUG(8,("_svcctl_enum_external_services: enumerating %d external services starting at index %d\n", num_services,existing_services)); + DEBUG(8,("enum_external_services: enumerating %d external services starting at index %d\n", num_services,existing_services)); while (*svcname) { - DEBUG(10,("_svcctl_enum_external_services: Reading information on service %s, index %d\n",*svcname,i)); + DEBUG(10,("enum_external_services: Reading information on service %s, index %d\n",*svcname,i)); /* _svcctl_get_LSB_data(*svcname,si); */ - if (!_svcctl_read_service_tdb_to_si(service_tdb,*svcname, si)) { - DEBUG(1,("_svcctl_enum_external_services: CAN'T FIND INFO FOR SERVICE %s in the services DB\n",*svcname)); + if (!read_service_tdb_to_si(service_tdb,*svcname, si)) { + DEBUG(1,("enum_external_services: CAN'T FIND INFO FOR SERVICE %s in the services DB\n",*svcname)); } if ((si->filename == NULL) || (*si->filename == 0)) { @@ -922,7 +823,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc /* TODO - we could keep the following info in the DB, too... */ - DEBUG(8,("_svcctl_enum_external_services: Service name [%s] displayname [%s]\n", + DEBUG(8,("enum_external_services: Service name [%s] displayname [%s]\n", si->filename, si->provides)); services[i].status.type = SVCCTL_WIN32_OWN_PROC; services[i].status.win32_exit_code = 0x0; @@ -935,7 +836,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc memset(command, 0, sizeof(command)); slprintf(command, sizeof(command)-1, "%s%s%s %s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, *svcname, "status"); - DEBUG(10, ("_svcctl_enum_external_services: status command is [%s]\n", command)); + DEBUG(10, ("enum_external_services: status command is [%s]\n", command)); /* TODO - wrap in privilege check */ @@ -943,7 +844,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc DEBUGADD(10, ("returned [%d]\n", ret)); close(fd); if(ret != 0) - DEBUG(10, ("_svcctl_enum_external_services: Command returned [%d]\n", ret)); + DEBUG(10, ("enum_external_services: Command returned [%d]\n", ret)); services[i].status.state = SVCCTL_STOPPED; if (ret == 0) { services[i].status.state = SVCCTL_RUNNING; @@ -956,7 +857,7 @@ WERROR _svcctl_enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc i++; } - DEBUG(10,("_svcctl_enum_external_services: Read services %d\n",num_services)); + DEBUG(10,("enum_external_services: Read services %d\n",num_services)); *added = num_services; return WERR_OK; @@ -1111,7 +1012,7 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT DEBUG(8,("_svcctl_enum_services_status: Got %d internal services\n", num_int_services)); } - ext_result=_svcctl_enum_external_services(p->mem_ctx, &services, num_int_services, &num_ext_services); + ext_result=enum_external_services(p->mem_ctx, &services, num_int_services, &num_ext_services); if (W_ERROR_IS_OK(ext_result)) { DEBUG(8,("_svcctl_enum_services_status: Got %d external services\n", num_ext_services)); @@ -1166,18 +1067,15 @@ WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCT WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u) { - Service_info *service_info; +#if 0 + SERVICE_INFO *service_info; POLICY_HND *handle; pstring command; - fstring fhandle_string; SERVICE_STATUS *service_status; int ret,fd; /* need to find the service name by the handle that is open */ handle = &(q_u->handle); - policy_handle_to_string(&q_u->handle, &fhandle_string); - - DEBUG(10, ("_svcctl_control_service: Looking for handle [%s]\n",fhandle_string)); service_info = find_service_info_by_hnd(p, handle); @@ -1219,7 +1117,7 @@ WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, S close(fd); if(ret != 0) - DEBUG(10, ("_svcctl_enum_external_services: Command returned [%d]\n", ret)); + DEBUG(10, ("enum_external_services: Command returned [%d]\n", ret)); /* SET all service_stats bits here...*/ if (ret == 0) { @@ -1232,7 +1130,7 @@ WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, S DEBUG(10, ("_svcctl_query_service_config: Should call the commFound service [%s], [%s]\n",service_info->servicename,service_info->filename)); - /* no dependent services...basically a stub function */ +#endif return WERR_OK; } @@ -1262,11 +1160,9 @@ WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u ) { SERVICE_STATUS_PROCESS ssp; - fstring fhandle_string; POLICY_HND *handle; - Service_info *service_info; + SERVICE_INFO *service_info; pstring command; - int ret,fd; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ @@ -1275,9 +1171,7 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ /* need to find the service name by the handle that is open */ handle = &(q_u->handle); - policy_handle_to_string(&q_u->handle, &fhandle_string); - DEBUG(10, ("_svcctl_query_service_status_ex Looking for handle [%s]\n",fhandle_string)); /* get rid of the easy errors */ @@ -1300,19 +1194,19 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ ZERO_STRUCT(ssp); +#if 0 if (!strwicmp(service_info->servicetype,"EXTERNAL")) ssp.type = SVCCTL_WIN32_OWN_PROC; else ssp.type = SVCCTL_WIN32_SHARED_PROC; +#endif /* Get the status of the service.. */ - DEBUG(10, ("_svcctl_query_service_status_ex: Found service [%s], [%s]\n",service_info->servicename,service_info->filename)); - memset(command, 0, sizeof(command)); - slprintf(command, sizeof(command)-1, "%s%s%s %s", - dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service_info->filename, "status"); +#if 0 + slprintf(command, sizeof(command)-1, "%s%s%s %s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service_info->filename, "status"); DEBUG(10, ("_svcctl_query_service_status_ex: status command is [%s]\n", command)); @@ -1332,6 +1226,7 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ ssp.state = SVCCTL_STOPPED; ssp.controls_accepted = 0; } +#endif return WERR_OK; } @@ -1341,11 +1236,8 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u ) { - /* SERVICE_CONFIG *service_config = NULL; */ - fstring fhandle_string; POLICY_HND *handle; - Service_info *service_info; - pstring fullpathinfo; + SERVICE_INFO *service_info; uint32 needed_size; /* we have to set the outgoing buffer size to the same as the @@ -1355,9 +1247,6 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON /* need to find the service name by the handle that is open */ handle = &(q_u->handle); - policy_handle_to_string(&q_u->handle, &fhandle_string); - - DEBUG(10, ("_svcctl_query_service_config: Looking for handle [%s]\n",fhandle_string)); service_info = find_service_info_by_hnd(p, handle); @@ -1395,12 +1284,10 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON r_u->config.startname = TALLOC_ZERO_P(p->mem_ctx, UNISTR2); r_u->config.displayname = TALLOC_ZERO_P(p->mem_ctx, UNISTR2); - DEBUG(10, ("_svcctl_query_service_config: Found service [%s], [%s]\n",service_info->servicename,service_info->filename)); - +#if 0 pstrcpy(fullpathinfo,dyn_LIBDIR); pstrcat(fullpathinfo,SVCCTL_SCRIPT_DIR); pstrcat(fullpathinfo,service_info->filename); - /* Get and calculate the size of the fields. Note that we're still building the fields in the "too-small buffer case" even though we throw it away. */ @@ -1413,6 +1300,7 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON init_unistr2(r_u->config.startname,"LocalSystem",UNI_STR_TERMINATE); init_unistr2(r_u->config.displayname,service_info->servicename,UNI_STR_TERMINATE); +#endif needed_size = 0x04 + sizeof(SERVICE_CONFIG)+ 2*( r_u->config.executablepath->uni_str_len + @@ -1447,10 +1335,9 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG2 *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u ) { - fstring fhandle_string; POLICY_HND *handle; - Service_info *service_info; - uint32 level, string_buffer_size; + SERVICE_INFO *service_info; + uint32 level; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ @@ -1461,9 +1348,6 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO r_u->offset = 4; handle = &(q_u->handle); - policy_handle_to_string(&(q_u->handle), &fhandle_string); - - DEBUG(10, ("_svcctl_query_service_config2: Looking for handle [%s]\n",fhandle_string)); service_info = find_service_info_by_hnd(p, handle); @@ -1478,9 +1362,8 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO */ level = q_u->info_level; - DEBUG(10, ("_svcctl_query_service_config2: Found service [%s], [%s]\n",service_info->servicename,service_info->filename)); - DEBUG(10, ("_svcctl_query_service_config2: Looking for level [%x], buffer size is [%x]\n",level,q_u->buffer_size)); +#if 0 if (SERVICE_CONFIG_DESCRIPTION == level) { if (service_info && service_info->shortdescription) { /* length of the string, plus the terminator... */ @@ -1509,6 +1392,7 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO return WERR_OK; } +#endif return WERR_ACCESS_DENIED; } |