diff options
author | Gerald Carter <jerry@samba.org> | 2005-10-06 17:48:03 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:04:53 -0500 |
commit | 0bf72b6e330a76bee502cb36c1cb80c46d47d33c (patch) | |
tree | 565aaccd5faf27918b3fad5b3ac553cd14cec835 /source3/services | |
parent | 6de37ee5f5d015904e650df3112cf725ab0f1cb8 (diff) | |
download | samba-0bf72b6e330a76bee502cb36c1cb80c46d47d33c.tar.gz |
r10781: merging eventlog and svcctl code from trunk
(This used to be commit f10aa9fb84bfac4f1a22b74d63999668700ffaac)
Diffstat (limited to 'source3/services')
-rw-r--r-- | source3/services/services_db.c | 238 | ||||
-rw-r--r-- | source3/services/svc_rcinit.c | 148 | ||||
-rw-r--r-- | source3/services/svc_wins.c | 66 |
3 files changed, 273 insertions, 179 deletions
diff --git a/source3/services/services_db.c b/source3/services/services_db.c index b59cd5330e5..7c75d413528 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -23,6 +23,58 @@ #include "includes.h" +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 }, + { NULL, NULL, NULL, NULL } +}; + + /******************************************************************** ********************************************************************/ @@ -63,11 +115,122 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx ) Display name, Description, etc... ********************************************************************/ +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; + char *p, *s; + + 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; + } + + while ( (s = x_fgets( str, sizeof(str)-1, f )) != NULL ) { + /* 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... +********************************************************************/ + static void fill_service_values( const char *name, REGVAL_CTR *values ) { UNISTR2 data, dname, ipath, description; uint32 dword; pstring pstr; + int i; /* These values are hardcoded in all QueryServiceConfig() replies. I'm just storing them here for cosmetic purposes */ @@ -88,30 +251,39 @@ static void fill_service_values( const char *name, REGVAL_CTR *values ) /* special considerations for internal services and the DisplayName value */ - if ( strequal(name, "Spooler") ) { - pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR ); - init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); - init_unistr2( &description, "Internal service for spooling files to print devices", UNI_STR_TERMINATE ); - init_unistr2( &dname, "Print Spooler", UNI_STR_TERMINATE ); - } - else if ( strequal(name, "NETLOGON") ) { - pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR ); - init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); - init_unistr2( &description, "File service providing access to policy and profile data", UNI_STR_TERMINATE ); - init_unistr2( &dname, "Net Logon", UNI_STR_TERMINATE ); + 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; + } } - else if ( strequal(name, "RemoteRegistry") ) { - pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR ); - init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); - init_unistr2( &description, "Internal service providing remote access to the Samba registry", UNI_STR_TERMINATE ); - init_unistr2( &dname, "Remote Registry Service", UNI_STR_TERMINATE ); - } - else { + + /* 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; + pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, name ); init_unistr2( &ipath, pstr, UNI_STR_TERMINATE ); - init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE ); - init_unistr2( &dname, name, UNI_STR_TERMINATE ); + + /* 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 ); + } } + + /* add the new values */ + 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); @@ -248,9 +420,8 @@ void svcctl_init_keys( void ) /* the builting services exist */ - add_new_svc_name( key, subkeys, "Spooler" ); - add_new_svc_name( key, subkeys, "NETLOGON" ); - add_new_svc_name( key, subkeys, "RemoteRegistry" ); + for ( i=0; builtin_svcs[i].servicename; i++ ) + add_new_svc_name( key, subkeys, builtin_svcs[i].servicename ); for ( i=0; service_list[i]; i++ ) { @@ -352,29 +523,34 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL ); + wresult = regkey_open_internal( &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); - return NULL; + goto fail; } if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); TALLOC_FREE( key ); - return NULL; + goto fail; } fetch_reg_values( key, values ); if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) ) - fstrcpy( display_name, name ); - else - rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 ); + goto fail; + + rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 ); TALLOC_FREE( key ); return display_name; + +fail: + /* default to returning the service name */ + fstrcpy( display_name, name ); + return display_name; } /******************************************************************** @@ -392,7 +568,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL ); + wresult = regkey_open_internal( &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); @@ -431,7 +607,7 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) /* now add the security descriptor */ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name ); - wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL ); + wresult = regkey_open_internal( &key, path, token, REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); diff --git a/source3/services/svc_rcinit.c b/source3/services/svc_rcinit.c index 5801d076c49..f60019601fe 100644 --- a/source3/services/svc_rcinit.c +++ b/source3/services/svc_rcinit.c @@ -1,4 +1,3 @@ - /* * Unix SMB/CIFS implementation. * Service Control API Implementation @@ -21,153 +20,6 @@ #include "includes.h" -/* Implementation for LSB compliant init scripts */ - -/******************************************************************************* - Get the services information by reading and parsing the shell scripts. These - are symbolically linked into the SVCCTL_SCRIPT_DIR directory. - - Get the names of the services/scripts to read from the smb.conf file. -*******************************************************************************/ - -BOOL get_LSB_data(char *fname,Service_info *si ) -{ - pstring initdfile; - char mybuffer[256]; - const char *tokenptr; - char **qlines; - int fd = -1; - int nlines, *numlines,i,in_section,in_description; - - pstrcpy(si->servicename,""); - pstrcpy(si->servicetype,"EXTERNAL"); - pstrcpy(si->filename,fname); - pstrcpy(si->provides,""); - pstrcpy(si->dependencies,""); - pstrcpy(si->shouldstart,""); - pstrcpy(si->shouldstop,""); - pstrcpy(si->requiredstart,""); - pstrcpy(si->requiredstop,""); - pstrcpy(si->description,""); - pstrcpy(si->shortdescription,""); - - numlines = &nlines; - in_section = 0; - in_description = 0; - - - if( !fname || !*fname ) { - DEBUG(0, ("Must define an \"LSB-style init file\" to read.\n")); - return False; - } - pstrcpy(initdfile,dyn_LIBDIR); - pstrcat(initdfile,SVCCTL_SCRIPT_DIR); - pstrcat(initdfile,fname); - - /* TODO - should check to see if the file that we're trying to open is - actually a script. If it's NOT, we should do something like warn, - and not continue to try to find info we're looking for */ - - DEBUG(10, ("Opening [%s]\n", initdfile)); - fd = -1; - fd = open(initdfile,O_RDONLY); - *numlines = 0; - - if (fd == -1) { - DEBUG(10, ("Couldn't open [%s]\n", initdfile)); - return False; - } - - qlines = fd_lines_load(fd, numlines); - DEBUGADD(10, ("Lines returned = [%d]\n", *numlines)); - close(fd); - - - if (*numlines) { - - for(i = 0; i < *numlines; i++) { - - DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i])); - if (!in_section && (0==strwicmp("### BEGIN INIT INFO", qlines[i]))) { - /* we now can look for params */ - DEBUGADD(10, ("Configuration information starts on line = [%d]\n", i)); - in_section = 1; - - } else if (in_section && (0==strwicmp("### END INIT INFO", qlines[i]))) { - DEBUGADD(10, ("Configuration information ends on line = [%d]\n", i)); - DEBUGADD(10, ("Description is [%s]\n", si->description)); - in_description = 0; - in_section = 0; - break; - } else if (in_section) { - tokenptr = qlines[i]; - if (in_description) { - DEBUGADD(10, ("Processing DESCRIPTION [%d]\n", *tokenptr)); - if (tokenptr && (*tokenptr=='#') && (*(tokenptr+1)=='\t')) { - DEBUGADD(10, ("Adding to DESCRIPTION [%d]\n", *tokenptr)); - pstrcat(si->description," "); - pstrcat(si->description,tokenptr+2); - continue; - } - in_description = 0; - DEBUGADD(10, ("Not a description!\n")); - } - if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) { - DEBUGADD(10, ("Invalid line [%d]\n", i)); - break; /* bad line? */ - } - if (0 != strncmp(mybuffer,"#",1)) { - DEBUGADD(10, ("Invalid line [%d], is %s\n", i,mybuffer)); - break; - } - if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) { - DEBUGADD(10, ("Invalid token on line [%d]\n", i)); - break; /* bad line? */ - } - DEBUGADD(10, ("Keyword is [%s]\n", mybuffer)); - if (0==strwicmp(mybuffer,"Description:")) { - while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) { - tokenptr++; - } - pstrcpy(si->description,tokenptr); - DEBUGADD(10, ("FOUND DESCRIPTION! Data is [%s]\n", tokenptr)); - in_description = 1; - } else { - while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) { - tokenptr++; - } - DEBUGADD(10, ("Data is [%s]\n", tokenptr)); - in_description = 0; - - /* save certain keywords, don't save others */ - if (0==strwicmp(mybuffer, "Provides:")) { - pstrcpy(si->provides,tokenptr); - pstrcpy(si->servicename,tokenptr); - } - - if (0==strwicmp(mybuffer, "Short-Description:")) { - pstrcpy(si->shortdescription,tokenptr); - } - - if (0==strwicmp(mybuffer, "Required-start:")) { - pstrcpy(si->requiredstart,tokenptr); - pstrcpy(si->dependencies,tokenptr); - } - - if (0==strwicmp(mybuffer, "Should-start:")) { - pstrcpy(si->shouldstart,tokenptr); - } - } - } - } - - file_lines_free(qlines); - return True; - } - - return False; -} - /********************************************************************* *********************************************************************/ diff --git a/source3/services/svc_wins.c b/source3/services/svc_wins.c new file mode 100644 index 00000000000..3a4650664df --- /dev/null +++ b/source3/services/svc_wins.c @@ -0,0 +1,66 @@ +/* + * Unix SMB/CIFS implementation. + * Service Control API Implementation + * Copyright (C) Gerald 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" + +/* Implementation for internal wins service */ + +/********************************************************************* +*********************************************************************/ + +static WERROR wins_stop( const char *service, SERVICE_STATUS *service_status ) +{ + return WERR_ACCESS_DENIED; +} + +/********************************************************************* +*********************************************************************/ + +static WERROR wins_start( const char *service ) +{ + return WERR_ACCESS_DENIED; +} + +/********************************************************************* +*********************************************************************/ + +static WERROR wins_status( const char *service, SERVICE_STATUS *service_status ) +{ + ZERO_STRUCTP( service_status ); + + service_status->type = 0x10; + if ( lp_wins_support() ) + service_status->state = SVCCTL_RUNNING; + else + service_status->state = SVCCTL_STOPPED; + + return WERR_OK; +} + +/********************************************************************* +*********************************************************************/ + +/* struct for svcctl control to manipulate wins service */ + +SERVICE_CONTROL_OPS wins_svc_ops = { + wins_stop, + wins_start, + wins_status +}; |