summaryrefslogtreecommitdiff
path: root/source3/services
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-10-06 17:48:03 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:53 -0500
commit0bf72b6e330a76bee502cb36c1cb80c46d47d33c (patch)
tree565aaccd5faf27918b3fad5b3ac553cd14cec835 /source3/services
parent6de37ee5f5d015904e650df3112cf725ab0f1cb8 (diff)
downloadsamba-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.c238
-rw-r--r--source3/services/svc_rcinit.c148
-rw-r--r--source3/services/svc_wins.c66
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
+};