Merge branch 'master' of ssh://git.samba.org/data/git/samba
[kai/samba.git] / source3 / services / svc_rcinit.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Service Control API Implementation
4  *  Copyright (C) Gerald Carter                   2005.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21
22 /*********************************************************************
23 *********************************************************************/
24
25 static WERROR rcinit_stop( const char *service, struct SERVICE_STATUS *status )
26 {
27         char *command = NULL;
28         int ret, fd;
29
30         if (asprintf(&command, "%s/%s/%s stop",
31                                 get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
32                 return WERR_NOMEM;
33         }
34
35         /* we've already performed the access check when the service was opened */
36
37         become_root();
38         ret = smbrun( command , &fd );
39         unbecome_root();
40
41         DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
42         close(fd);
43
44         SAFE_FREE(command);
45
46         ZERO_STRUCTP( status );
47
48         status->type                    = SERVICE_TYPE_WIN32_SHARE_PROCESS;
49         status->state                   = (ret == 0 ) ? SVCCTL_STOPPED : SVCCTL_RUNNING;
50         status->controls_accepted       = SVCCTL_ACCEPT_STOP |
51                                           SVCCTL_ACCEPT_SHUTDOWN;
52
53         return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
54 }
55
56 /*********************************************************************
57 *********************************************************************/
58
59 static WERROR rcinit_start( const char *service )
60 {
61         char *command = NULL;
62         int ret, fd;
63
64         if (asprintf(&command, "%s/%s/%s start",
65                                 get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
66                 return WERR_NOMEM;
67         }
68
69         /* we've already performed the access check when the service was opened */
70
71         become_root();
72         ret = smbrun( command , &fd );
73         unbecome_root();
74
75         DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
76         close(fd);
77
78         SAFE_FREE(command);
79
80         return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
81 }
82
83 /*********************************************************************
84 *********************************************************************/
85
86 static WERROR rcinit_status( const char *service, struct SERVICE_STATUS *status )
87 {
88         char *command = NULL;
89         int ret, fd;
90
91         if (asprintf(&command, "%s/%s/%s status",
92                                 get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
93                 return WERR_NOMEM;
94         }
95
96         /* we've already performed the access check when the service was opened */
97         /* assume as return code of 0 means that the service is ok.  Anything else
98            is STOPPED */
99
100         become_root();
101         ret = smbrun( command , &fd );
102         unbecome_root();
103
104         DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
105         close(fd);
106
107         SAFE_FREE(command);
108
109         ZERO_STRUCTP( status );
110
111         status->type                    = SERVICE_TYPE_WIN32_SHARE_PROCESS;
112         status->state                   = (ret == 0 ) ? SVCCTL_RUNNING : SVCCTL_STOPPED;
113         status->controls_accepted       = SVCCTL_ACCEPT_STOP |
114                                           SVCCTL_ACCEPT_SHUTDOWN;
115
116         return WERR_OK;
117 }
118
119 /*********************************************************************
120 *********************************************************************/
121
122 /* struct for svcctl control to manipulate rcinit service */
123
124 SERVICE_CONTROL_OPS rcinit_svc_ops = {
125         rcinit_stop,
126         rcinit_start,
127         rcinit_status
128 };