-
-/*
+/*
* 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
+ * the Free Software Foundation; either version 3 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#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 )
+static WERROR rcinit_stop( const char *service, struct SERVICE_STATUS *status )
{
- 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;
+ char *command = NULL;
+ int ret, fd;
+
+ if (asprintf(&command, "%s/%s/%s stop",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOMEM;
}
- qlines = fd_lines_load(fd, numlines);
- DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
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;
-}
+ SAFE_FREE(command);
-/*********************************************************************
-*********************************************************************/
+ ZERO_STRUCTP( status );
-static WERROR rcinit_stop( void )
-{
- return WERR_OK;
+ status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ status->state = (ret == 0 ) ? SVCCTL_STOPPED : SVCCTL_RUNNING;
+ status->controls_accepted = SVCCTL_ACCEPT_STOP |
+ SVCCTL_ACCEPT_SHUTDOWN;
+
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
}
/*********************************************************************
*********************************************************************/
-static WERROR rcinit_start( void )
+static WERROR rcinit_start( const char *service )
{
- return WERR_OK;
+ char *command = NULL;
+ int ret, fd;
+
+ if (asprintf(&command, "%s/%s/%s start",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOMEM;
+ }
+
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ SAFE_FREE(command);
+
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
}
/*********************************************************************
*********************************************************************/
-static WERROR rcinit_status( SERVICE_STATUS *service_status )
+static WERROR rcinit_status( const char *service, struct SERVICE_STATUS *status )
{
+ char *command = NULL;
+ int ret, fd;
+
+ if (asprintf(&command, "%s/%s/%s status",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOMEM;
+ }
+
+ /* we've already performed the access check when the service was opened */
+ /* assume as return code of 0 means that the service is ok. Anything else
+ is STOPPED */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ SAFE_FREE(command);
+
+ ZERO_STRUCTP( status );
+
+ status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ status->state = (ret == 0 ) ? SVCCTL_RUNNING : SVCCTL_STOPPED;
+ status->controls_accepted = SVCCTL_ACCEPT_STOP |
+ SVCCTL_ACCEPT_SHUTDOWN;
+
return WERR_OK;
}