2005-06-15 04:54:43 +04:00
/*
* Unix SMB / CIFS implementation .
* Service Control API Implementation
2005-09-30 21:13:37 +04:00
*
2005-06-15 04:54:43 +04:00
* Copyright ( C ) Marcin Krzysztof Porwit 2005.
2005-09-30 21:13:37 +04:00
* Largely Rewritten by :
* Copyright ( C ) Gerald ( Jerry ) Carter 2005.
2005-06-15 04:54:43 +04:00
*
* 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 0213 9 , USA .
*/
# include "includes.h"
2005-10-06 21:48:03 +04:00
struct rcinit_file_information {
char * description ;
} ;
struct service_display_info {
const char * servicename ;
const char * daemon ;
const char * dispname ;
const char * description ;
} ;
struct service_display_info builtin_svcs [ ] = {
{ " Spooler " , " smbd " , " Print Spooler " ,
" Internal service for spooling files to print devices " } ,
{ " NETLOGON " , " smbd " , " Net Logon " ,
" File service providing access to policy and profile data " } ,
{ " RemoteRegistry " , " smbd " , " Remote Registry Service " ,
" Internal service providing remote access to the Samba registry " } ,
{ " WINS " , " nmbd " , " Windows Internet Name Service (WINS) " ,
" Internal service providing a NetBIOS point-to-point name server " } ,
{ NULL , NULL , NULL , NULL }
} ;
struct service_display_info common_unix_svcs [ ] = {
{ " cups " , NULL , " Common Unix Printing System " , NULL } ,
{ " postfix " , NULL , " Internet Mail Service " , NULL } ,
{ " sendmail " , NULL , " Internet Mail Service " , NULL } ,
{ " portmap " , NULL , " TCP Port to RPC PortMapper " , NULL } ,
{ " xinetd " , NULL , " Internet Meta-Daemon " , NULL } ,
{ " inet " , NULL , " Internet Meta-Daemon " , NULL } ,
{ " xntpd " , NULL , " Network Time Service " , NULL } ,
{ " ntpd " , NULL , " Network Time Service " , NULL } ,
{ " lpd " , NULL , " BSD Print Spooler " , NULL } ,
{ " nfsserver " , NULL , " Network File Service " , NULL } ,
{ " cron " , NULL , " Scheduling Service " , NULL } ,
{ " at " , NULL , " Scheduling Service " , NULL } ,
{ " nscd " , NULL , " Name Service Cache Daemon " , NULL } ,
{ " slapd " , NULL , " LDAP Directory Service " , NULL } ,
{ " ldap " , NULL , " LDAP DIrectory Service " , NULL } ,
{ " ypbind " , NULL , " NIS Directory Service " , NULL } ,
{ " courier-imap " , NULL , " IMAP4 Mail Service " , NULL } ,
{ " courier-pop3 " , NULL , " POP3 Mail Service " , NULL } ,
{ " named " , NULL , " Domain Name Service " , NULL } ,
{ " bind " , NULL , " Domain Name Service " , NULL } ,
{ " httpd " , NULL , " HTTP Server " , NULL } ,
{ " apache " , NULL , " HTTP Server " , NULL } ,
{ " autofs " , NULL , " Automounter " , NULL } ,
{ " squid " , NULL , " Web Cache Proxy " , NULL } ,
2005-11-08 19:33:45 +03:00
{ " perfcountd " , NULL , " Performance Monitoring Daemon " , NULL } ,
2005-10-06 21:48:03 +04:00
{ NULL , NULL , NULL , NULL }
} ;
2005-09-30 21:13:37 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
static SEC_DESC * construct_service_sd ( TALLOC_CTX * ctx )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
SEC_ACE ace [ 4 ] ;
SEC_ACCESS mask ;
size_t i = 0 ;
SEC_DESC * sd ;
SEC_ACL * acl ;
size_t sd_size ;
/* basic access for Everyone */
init_sec_access ( & mask , SERVICE_READ_ACCESS ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_access ( & mask , SERVICE_EXECUTE_ACCESS ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Power_Users , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_access ( & mask , SERVICE_ALL_ACCESS ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Server_Operators , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
/* create the security descriptor */
if ( ! ( acl = make_sec_acl ( ctx , NT4_ACL_REVISION , i , ace ) ) )
return NULL ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
if ( ! ( sd = make_sec_desc ( ctx , SEC_DESC_REVISION , SEC_DESC_SELF_RELATIVE , NULL , NULL , NULL , acl , & sd_size ) ) )
return NULL ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
return sd ;
}
2005-06-15 04:54:43 +04:00
/********************************************************************
2005-09-30 21:13:37 +04:00
This is where we do the dirty work of filling in things like the
Display name , Description , etc . . .
2005-06-15 04:54:43 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-06 21:48:03 +04:00
static char * get_common_service_dispname ( const char * servicename )
{
static fstring dispname ;
int i ;
for ( i = 0 ; common_unix_svcs [ i ] . servicename ; i + + ) {
if ( strequal ( servicename , common_unix_svcs [ i ] . servicename ) ) {
fstr_sprintf ( dispname , " %s (%s) " ,
common_unix_svcs [ i ] . dispname ,
common_unix_svcs [ i ] . servicename ) ;
return dispname ;
}
}
fstrcpy ( dispname , servicename ) ;
return dispname ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * cleanup_string ( const char * string )
{
static pstring clean ;
char * begin , * end ;
pstrcpy ( clean , string ) ;
begin = clean ;
/* trim any beginning whilespace */
while ( isspace ( * begin ) )
begin + + ;
if ( ! begin )
return NULL ;
/* trim any trailing whitespace or carriage returns.
Start at the end and move backwards */
end = begin + strlen ( begin ) - 1 ;
while ( isspace ( * end ) | | * end = = ' \n ' | | * end = = ' \r ' ) {
* end = ' \0 ' ;
end - - ;
}
return begin ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL read_init_file ( const char * servicename , struct rcinit_file_information * * service_info )
{
struct rcinit_file_information * info ;
pstring filepath , str ;
XFILE * f ;
2005-10-13 17:20:26 +04:00
char * p ;
2005-10-06 21:48:03 +04:00
if ( ! ( info = TALLOC_ZERO_P ( NULL , struct rcinit_file_information ) ) )
return False ;
/* attempt the file open */
pstr_sprintf ( filepath , " %s/%s/%s " , dyn_LIBDIR , SVCCTL_SCRIPT_DIR , servicename ) ;
if ( ! ( f = x_fopen ( filepath , O_RDONLY , 0 ) ) ) {
DEBUG ( 0 , ( " read_init_file: failed to open [%s] \n " , filepath ) ) ;
TALLOC_FREE ( info ) ;
return False ;
}
2005-10-13 17:20:26 +04:00
while ( ( x_fgets ( str , sizeof ( str ) - 1 , f ) ) ! = NULL ) {
2005-10-06 21:48:03 +04:00
/* ignore everything that is not a full line
comment starting with a ' # ' */
if ( str [ 0 ] ! = ' # ' )
continue ;
/* Look for a line like '^#.*Description:' */
if ( ( p = strstr ( str , " Description: " ) ) ! = NULL ) {
char * desc ;
p + = strlen ( " Description: " ) + 1 ;
if ( ! p )
break ;
if ( ( desc = cleanup_string ( p ) ) ! = NULL )
info - > description = talloc_strdup ( info , desc ) ;
}
}
x_fclose ( f ) ;
if ( ! info - > description )
info - > description = talloc_strdup ( info , " External Unix Service " ) ;
* service_info = info ;
return True ;
}
/********************************************************************
This is where we do the dirty work of filling in things like the
Display name , Description , etc . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
static void fill_service_values ( const char * name , REGVAL_CTR * values )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
UNISTR2 data , dname , ipath , description ;
uint32 dword ;
pstring pstr ;
2005-10-06 21:48:03 +04:00
int i ;
2005-09-30 21:13:37 +04:00
/* These values are hardcoded in all QueryServiceConfig() replies.
I ' m just storing them here for cosmetic purposes */
dword = SVCCTL_AUTO_START ;
regval_ctr_addvalue ( values , " Start " , REG_DWORD , ( char * ) & dword , sizeof ( uint32 ) ) ;
dword = SVCCTL_WIN32_OWN_PROC ;
regval_ctr_addvalue ( values , " Type " , REG_DWORD , ( char * ) & dword , sizeof ( uint32 ) ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
dword = SVCCTL_SVC_ERROR_NORMAL ;
regval_ctr_addvalue ( values , " ErrorControl " , REG_DWORD , ( char * ) & dword , sizeof ( uint32 ) ) ;
/* everything runs as LocalSystem */
init_unistr2 ( & data , " LocalSystem " , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " ObjectName " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * 2 ) ;
/* special considerations for internal services and the DisplayName value */
2005-10-06 21:48:03 +04:00
for ( i = 0 ; builtin_svcs [ i ] . servicename ; i + + ) {
if ( strequal ( name , builtin_svcs [ i ] . servicename ) ) {
pstr_sprintf ( pstr , " %s/%s/%s " , dyn_LIBDIR , SVCCTL_SCRIPT_DIR , builtin_svcs [ i ] . daemon ) ;
init_unistr2 ( & ipath , pstr , UNI_STR_TERMINATE ) ;
init_unistr2 ( & description , builtin_svcs [ i ] . description , UNI_STR_TERMINATE ) ;
init_unistr2 ( & dname , builtin_svcs [ i ] . dispname , UNI_STR_TERMINATE ) ;
break ;
}
2005-09-30 21:13:37 +04:00
}
2005-10-06 21:48:03 +04:00
/* default to an external service if we haven't found a match */
if ( builtin_svcs [ i ] . servicename = = NULL ) {
struct rcinit_file_information * init_info = NULL ;
2005-09-30 21:13:37 +04:00
pstr_sprintf ( pstr , " %s/%s/%s " , dyn_LIBDIR , SVCCTL_SCRIPT_DIR , name ) ;
init_unistr2 ( & ipath , pstr , UNI_STR_TERMINATE ) ;
2005-10-06 21:48:03 +04:00
/* lookup common unix display names */
init_unistr2 ( & dname , get_common_service_dispname ( name ) , UNI_STR_TERMINATE ) ;
/* get info from init file itself */
if ( read_init_file ( name , & init_info ) ) {
init_unistr2 ( & description , init_info - > description , UNI_STR_TERMINATE ) ;
TALLOC_FREE ( init_info ) ;
}
else {
init_unistr2 ( & description , " External Unix Service " , UNI_STR_TERMINATE ) ;
}
2005-09-30 21:13:37 +04:00
}
2005-10-06 21:48:03 +04:00
/* add the new values */
2005-09-30 21:13:37 +04:00
regval_ctr_addvalue ( values , " DisplayName " , REG_SZ , ( char * ) dname . buffer , dname . uni_str_len * 2 ) ;
regval_ctr_addvalue ( values , " ImagePath " , REG_SZ , ( char * ) ipath . buffer , ipath . uni_str_len * 2 ) ;
regval_ctr_addvalue ( values , " Description " , REG_SZ , ( char * ) description . buffer , description . uni_str_len * 2 ) ;
return ;
2005-06-15 04:54:43 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
static void add_new_svc_name ( REGISTRY_KEY * key_parent , REGSUBKEY_CTR * subkeys ,
const char * name )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * key_service , * key_secdesc ;
WERROR wresult ;
pstring path ;
REGVAL_CTR * values ;
REGSUBKEY_CTR * svc_subkeys ;
SEC_DESC * sd ;
prs_struct ps ;
/* add to the list and create the subkey path */
regsubkey_ctr_addkey ( subkeys , name ) ;
store_reg_keys ( key_parent , subkeys ) ;
/* open the new service key */
pstr_sprintf ( path , " %s \\ %s " , KEY_SERVICES , name ) ;
wresult = regkey_open_internal ( & key_service , path , get_root_nt_token ( ) ,
REG_KEY_ALL ) ;
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " add_new_svc_name: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
return ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
/* add the 'Security' key */
if ( ! ( svc_subkeys = TALLOC_ZERO_P ( key_service , REGSUBKEY_CTR ) ) ) {
DEBUG ( 0 , ( " add_new_svc_name: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_service ) ;
2005-09-30 21:13:37 +04:00
return ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
fetch_reg_keys ( key_service , svc_subkeys ) ;
regsubkey_ctr_addkey ( svc_subkeys , " Security " ) ;
store_reg_keys ( key_service , svc_subkeys ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/* now for the service values */
if ( ! ( values = TALLOC_ZERO_P ( key_service , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " add_new_svc_name: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_service ) ;
2005-09-30 21:13:37 +04:00
return ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
fill_service_values ( name , values ) ;
store_reg_values ( key_service , values ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/* cleanup the service key*/
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_service ) ;
2005-09-30 21:13:37 +04:00
/* now add the security descriptor */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
pstr_sprintf ( path , " %s \\ %s \\ %s " , KEY_SERVICES , name , " Security " ) ;
wresult = regkey_open_internal ( & key_secdesc , path , get_root_nt_token ( ) ,
REG_KEY_ALL ) ;
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " add_new_svc_name: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_secdesc ) ;
2005-09-30 21:13:37 +04:00
return ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
if ( ! ( values = TALLOC_ZERO_P ( key_secdesc , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " add_new_svc_name: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_secdesc ) ;
2005-09-30 21:13:37 +04:00
return ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
if ( ! ( sd = construct_service_sd ( key_secdesc ) ) ) {
DEBUG ( 0 , ( " add_new_svc_name: Failed to create default sec_desc! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_secdesc ) ;
2005-09-30 21:13:37 +04:00
return ;
}
/* stream the printer security descriptor */
prs_init ( & ps , RPC_MAX_PDU_FRAG_LEN , key_secdesc , MARSHALL ) ;
if ( sec_io_desc ( " sec_desc " , & sd , & ps , 0 ) ) {
uint32 offset = prs_offset ( & ps ) ;
regval_ctr_addvalue ( values , " Security " , REG_BINARY , prs_data_p ( & ps ) , offset ) ;
store_reg_values ( key_secdesc , values ) ;
}
/* finally cleanup the Security key */
prs_mem_free ( & ps ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key_secdesc ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
return ;
2005-06-15 04:54:43 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
void svcctl_init_keys ( void )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
const char * * service_list = lp_svcctl_list ( ) ;
int i ;
REGSUBKEY_CTR * subkeys ;
REGISTRY_KEY * key = NULL ;
WERROR wresult ;
/* bad mojo here if the lookup failed. Should not happen */
wresult = regkey_open_internal ( & key , KEY_SERVICES , get_root_nt_token ( ) ,
REG_KEY_ALL ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " init_services_keys: key lookup failed! (%s) \n " ,
dos_errstr ( wresult ) ) ) ;
return ;
}
/* lookup the available subkeys */
if ( ! ( subkeys = TALLOC_ZERO_P ( key , REGSUBKEY_CTR ) ) ) {
DEBUG ( 0 , ( " init_services_keys: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return ;
}
fetch_reg_keys ( key , subkeys ) ;
/* the builting services exist */
2005-10-06 21:48:03 +04:00
for ( i = 0 ; builtin_svcs [ i ] . servicename ; i + + )
add_new_svc_name ( key , subkeys , builtin_svcs [ i ] . servicename ) ;
2005-09-30 21:13:37 +04:00
for ( i = 0 ; service_list [ i ] ; i + + ) {
/* only add new services */
if ( regsubkey_ctr_key_exists ( subkeys , service_list [ i ] ) )
continue ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/* Add the new service key and initialize the appropriate values */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
add_new_svc_name ( key , subkeys , service_list [ i ] ) ;
2005-06-15 04:54:43 +04:00
}
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/* initialize the control hooks */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
init_service_op_table ( ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
return ;
2005-06-15 04:54:43 +04:00
}
/********************************************************************
2005-09-30 21:13:37 +04:00
This is where we do the dirty work of filling in things like the
Display name , Description , etc . . . Always return a default secdesc
in case of any failure .
2005-06-15 04:54:43 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
SEC_DESC * svcctl_get_secdesc ( TALLOC_CTX * ctx , const char * name , NT_USER_TOKEN * token )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * key ;
prs_struct ps ;
REGVAL_CTR * values ;
REGISTRY_VALUE * val ;
SEC_DESC * sd = NULL ;
SEC_DESC * ret_sd = NULL ;
pstring path ;
WERROR wresult ;
/* now add the security descriptor */
pstr_sprintf ( path , " %s \\ %s \\ %s " , KEY_SERVICES , name , " Security " ) ;
wresult = regkey_open_internal ( & key , path , token , REG_KEY_ALL ) ;
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " svcctl_get_secdesc: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
return NULL ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
if ( ! ( values = TALLOC_ZERO_P ( key , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " add_new_svc_name: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return NULL ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
fetch_reg_values ( key , values ) ;
if ( ! ( val = regval_ctr_getvalue ( values , " Security " ) ) ) {
DEBUG ( 6 , ( " svcctl_get_secdesc: constructing default secdesc for service [%s] \n " ,
name ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return construct_service_sd ( ctx ) ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/* stream the printer security descriptor */
prs_init ( & ps , 0 , key , UNMARSHALL ) ;
2005-10-18 07:24:00 +04:00
prs_give_memory ( & ps , ( char * ) regval_data_p ( val ) , regval_size ( val ) , False ) ;
2005-09-30 21:13:37 +04:00
if ( ! sec_io_desc ( " sec_desc " , & sd , & ps , 0 ) ) {
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return construct_service_sd ( ctx ) ;
}
ret_sd = dup_sec_desc ( ctx , sd ) ;
/* finally cleanup the Security key */
prs_mem_free ( & ps ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
return ret_sd ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
char * svcctl_lookup_dispname ( const char * name , NT_USER_TOKEN * token )
{
static fstring display_name ;
REGISTRY_KEY * key ;
REGVAL_CTR * values ;
REGISTRY_VALUE * val ;
pstring path ;
WERROR wresult ;
/* now add the security descriptor */
pstr_sprintf ( path , " %s \\ %s " , KEY_SERVICES , name ) ;
2005-10-06 21:48:03 +04:00
wresult = regkey_open_internal ( & key , path , token , REG_KEY_READ ) ;
2005-09-30 21:13:37 +04:00
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " svcctl_lookup_dispname: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
2005-10-06 21:48:03 +04:00
goto fail ;
2005-09-30 21:13:37 +04:00
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
if ( ! ( values = TALLOC_ZERO_P ( key , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " svcctl_lookup_dispname: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-10-06 21:48:03 +04:00
goto fail ;
2005-09-30 21:13:37 +04:00
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
fetch_reg_values ( key , values ) ;
if ( ! ( val = regval_ctr_getvalue ( values , " DisplayName " ) ) )
2005-10-06 21:48:03 +04:00
goto fail ;
rpcstr_pull ( display_name , regval_data_p ( val ) , sizeof ( display_name ) , regval_size ( val ) , 0 ) ;
2005-06-15 04:54:43 +04:00
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return display_name ;
2005-10-06 21:48:03 +04:00
fail :
/* default to returning the service name */
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-10-06 21:48:03 +04:00
fstrcpy ( display_name , name ) ;
return display_name ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
char * svcctl_lookup_description ( const char * name , NT_USER_TOKEN * token )
2005-06-15 04:54:43 +04:00
{
2005-09-30 21:13:37 +04:00
static fstring description ;
REGISTRY_KEY * key ;
REGVAL_CTR * values ;
REGISTRY_VALUE * val ;
pstring path ;
WERROR wresult ;
/* now add the security descriptor */
pstr_sprintf ( path , " %s \\ %s " , KEY_SERVICES , name ) ;
2005-10-06 21:48:03 +04:00
wresult = regkey_open_internal ( & key , path , token , REG_KEY_READ ) ;
2005-09-30 21:13:37 +04:00
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " svcctl_lookup_dispname: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
return NULL ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
if ( ! ( values = TALLOC_ZERO_P ( key , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " svcctl_lookup_dispname: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return NULL ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
fetch_reg_values ( key , values ) ;
if ( ! ( val = regval_ctr_getvalue ( values , " Description " ) ) )
fstrcpy ( description , " Unix Service " ) ;
else
rpcstr_pull ( description , regval_data_p ( val ) , sizeof ( description ) , regval_size ( val ) , 0 ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
return description ;
}
2005-06-15 04:54:43 +04:00
2005-09-30 21:13:37 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
REGVAL_CTR * svcctl_fetch_regvalues ( const char * name , NT_USER_TOKEN * token )
{
REGISTRY_KEY * key ;
REGVAL_CTR * values ;
pstring path ;
WERROR wresult ;
/* now add the security descriptor */
pstr_sprintf ( path , " %s \\ %s " , KEY_SERVICES , name ) ;
2005-10-06 21:48:03 +04:00
wresult = regkey_open_internal ( & key , path , token , REG_KEY_READ ) ;
2005-09-30 21:13:37 +04:00
if ( ! W_ERROR_IS_OK ( wresult ) ) {
DEBUG ( 0 , ( " svcctl_fetch_regvalues: key lookup failed! [%s] (%s) \n " ,
path , dos_errstr ( wresult ) ) ) ;
return NULL ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
if ( ! ( values = TALLOC_ZERO_P ( NULL , REGVAL_CTR ) ) ) {
DEBUG ( 0 , ( " svcctl_fetch_regvalues: talloc() failed! \n " ) ) ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return NULL ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00
fetch_reg_values ( key , values ) ;
2005-06-15 04:54:43 +04:00
2005-10-07 16:14:25 +04:00
regkey_close_internal ( key ) ;
2005-09-30 21:13:37 +04:00
return values ;
2005-06-15 04:54:43 +04:00
}
2005-09-30 21:13:37 +04:00