s3-svcctl: use security descriptor marshall helper in svcctl_set_secdesc().
[kai/samba.git] / source3 / services / svc_rcinit.c
index a4046b351186c6c5a980aae83af596b9fb30c9f9..3f56676fe1497c58202f218465882415b598063f 100644 (file)
-
-/* 
+/*
  *  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;
 }