r23271: merge service control pidl change for CloseServiceHandle() from SAMBA_3_0_26
[sfrench/samba-autobuild/.git] / source / rpc_server / srv_svcctl.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Gerald Carter                   2005 - 2007
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 2 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, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_SRV
25
26 static BOOL proxy_svcctl_call(pipes_struct *p, uint8 opnum)
27 {
28         struct api_struct *fns;
29         int n_fns;
30
31         svcctl_get_pipe_fns(&fns, &n_fns);
32
33         if (opnum >= n_fns)
34                 return False;
35
36         if (fns[opnum].opnum != opnum) {
37                 smb_panic("SVCCTL function table not sorted\n");
38         }
39
40         return fns[opnum].fn(p);
41 }
42
43
44 /*******************************************************************
45  ********************************************************************/
46
47 static BOOL api_svcctl_close_service(pipes_struct *p)
48 {
49         return proxy_svcctl_call( p, DCERPC_SVCCTL_CLOSESERVICEHANDLE );
50 }
51
52 /*******************************************************************
53  ********************************************************************/
54
55 static BOOL api_svcctl_open_scmanager(pipes_struct *p)
56 {
57         SVCCTL_Q_OPEN_SCMANAGER q_u;
58         SVCCTL_R_OPEN_SCMANAGER r_u;
59         prs_struct *data = &p->in_data.data;
60         prs_struct *rdata = &p->out_data.rdata;
61
62         ZERO_STRUCT(q_u);
63         ZERO_STRUCT(r_u);
64
65         if(!svcctl_io_q_open_scmanager("", &q_u, data, 0))
66                 return False;
67
68         r_u.status = _svcctl_open_scmanager(p, &q_u, &r_u);
69
70         if(!svcctl_io_r_open_scmanager("", &r_u, rdata, 0))
71                 return False;
72
73         return True;
74 }
75
76 /*******************************************************************
77  ********************************************************************/
78
79 static BOOL api_svcctl_open_service(pipes_struct *p)
80 {
81         SVCCTL_Q_OPEN_SERVICE q_u;
82         SVCCTL_R_OPEN_SERVICE r_u;
83         prs_struct *data = &p->in_data.data;
84         prs_struct *rdata = &p->out_data.rdata;
85
86         ZERO_STRUCT(q_u);
87         ZERO_STRUCT(r_u);
88
89         if(!svcctl_io_q_open_service("", &q_u, data, 0))
90                 return False;
91
92         r_u.status = _svcctl_open_service(p, &q_u, &r_u);
93
94         if(!svcctl_io_r_open_service("", &r_u, rdata, 0))
95                 return False;
96
97         return True;
98 }
99
100 /*******************************************************************
101  ********************************************************************/
102
103 static BOOL api_svcctl_get_display_name(pipes_struct *p)
104 {
105         SVCCTL_Q_GET_DISPLAY_NAME q_u;
106         SVCCTL_R_GET_DISPLAY_NAME r_u;
107         prs_struct *data = &p->in_data.data;
108         prs_struct *rdata = &p->out_data.rdata;
109
110         ZERO_STRUCT(q_u);
111         ZERO_STRUCT(r_u);
112
113         if(!svcctl_io_q_get_display_name("", &q_u, data, 0))
114                 return False;
115
116         r_u.status = _svcctl_get_display_name(p, &q_u, &r_u);
117
118         if(!svcctl_io_r_get_display_name("", &r_u, rdata, 0))
119                 return False;
120
121         return True;
122 }
123
124 /*******************************************************************
125  ********************************************************************/
126
127 static BOOL api_svcctl_query_status(pipes_struct *p)
128 {
129         SVCCTL_Q_QUERY_STATUS q_u;
130         SVCCTL_R_QUERY_STATUS r_u;
131         prs_struct *data = &p->in_data.data;
132         prs_struct *rdata = &p->out_data.rdata;
133
134         ZERO_STRUCT(q_u);
135         ZERO_STRUCT(r_u);
136
137         if(!svcctl_io_q_query_status("", &q_u, data, 0))
138                 return False;
139
140         r_u.status = _svcctl_query_status(p, &q_u, &r_u);
141
142         if(!svcctl_io_r_query_status("", &r_u, rdata, 0))
143                 return False;
144
145         return True;
146 }
147
148 /*******************************************************************
149  ********************************************************************/
150
151 static BOOL api_svcctl_enum_services_status(pipes_struct *p)
152 {
153         SVCCTL_Q_ENUM_SERVICES_STATUS q_u;
154         SVCCTL_R_ENUM_SERVICES_STATUS r_u;
155         prs_struct *data = &p->in_data.data;
156         prs_struct *rdata = &p->out_data.rdata;
157
158         ZERO_STRUCT(q_u);
159         ZERO_STRUCT(r_u);
160
161         if(!svcctl_io_q_enum_services_status("", &q_u, data, 0))
162                 return False;
163
164         r_u.status = _svcctl_enum_services_status(p, &q_u, &r_u);
165
166         if(!svcctl_io_r_enum_services_status("", &r_u, rdata, 0))
167                 return False;
168
169         return True;
170 }
171 /*******************************************************************
172  ********************************************************************/
173
174 static BOOL api_svcctl_query_service_status_ex(pipes_struct *p)
175 {
176         SVCCTL_Q_QUERY_SERVICE_STATUSEX q_u;
177         SVCCTL_R_QUERY_SERVICE_STATUSEX r_u;
178         prs_struct *data = &p->in_data.data;
179         prs_struct *rdata = &p->out_data.rdata;
180
181         ZERO_STRUCT(q_u);
182         ZERO_STRUCT(r_u);
183
184         if(!svcctl_io_q_query_service_status_ex("", &q_u, data, 0))
185                 return False;
186
187         r_u.status = _svcctl_query_service_status_ex(p, &q_u, &r_u);
188
189         if(!svcctl_io_r_query_service_status_ex("", &r_u, rdata, 0))
190                 return False;
191
192         return True;
193 }
194 /*******************************************************************
195  ********************************************************************/
196
197 static BOOL api_svcctl_enum_dependent_services(pipes_struct *p)
198 {
199         SVCCTL_Q_ENUM_DEPENDENT_SERVICES q_u;
200         SVCCTL_R_ENUM_DEPENDENT_SERVICES r_u;
201         prs_struct *data = &p->in_data.data;
202         prs_struct *rdata = &p->out_data.rdata;
203
204         ZERO_STRUCT(q_u);
205         ZERO_STRUCT(r_u);
206
207         if(!svcctl_io_q_enum_dependent_services("", &q_u, data, 0))
208                 return False;
209
210         r_u.status = _svcctl_enum_dependent_services(p, &q_u, &r_u);
211
212         if(!svcctl_io_r_enum_dependent_services("", &r_u, rdata, 0))
213                 return False;
214
215         return True;
216 }
217
218 /*******************************************************************
219  ********************************************************************/
220
221 static BOOL api_svcctl_start_service(pipes_struct *p)
222 {
223         SVCCTL_Q_START_SERVICE q_u;
224         SVCCTL_R_START_SERVICE r_u;
225         prs_struct *data = &p->in_data.data;
226         prs_struct *rdata = &p->out_data.rdata;
227
228         ZERO_STRUCT(q_u);
229         ZERO_STRUCT(r_u);
230
231         if(!svcctl_io_q_start_service("", &q_u, data, 0))
232                 return False;
233
234         r_u.status = _svcctl_start_service(p, &q_u, &r_u);
235
236         if(!svcctl_io_r_start_service("", &r_u, rdata, 0))
237                 return False;
238
239         return True;
240 }
241
242 /*******************************************************************
243  ********************************************************************/
244
245 static BOOL api_svcctl_control_service(pipes_struct *p)
246 {
247         SVCCTL_Q_CONTROL_SERVICE q_u;
248         SVCCTL_R_CONTROL_SERVICE r_u;
249         prs_struct *data = &p->in_data.data;
250         prs_struct *rdata = &p->out_data.rdata;
251
252         ZERO_STRUCT(q_u);
253         ZERO_STRUCT(r_u);
254
255         if(!svcctl_io_q_control_service("", &q_u, data, 0))
256                 return False;
257
258         r_u.status = _svcctl_control_service(p, &q_u, &r_u);
259
260         if(!svcctl_io_r_control_service("", &r_u, rdata, 0))
261                 return False;
262
263         return True;
264 }
265
266 /*******************************************************************
267  ********************************************************************/
268
269 static BOOL api_svcctl_query_service_config(pipes_struct *p)
270 {
271         SVCCTL_Q_QUERY_SERVICE_CONFIG q_u;
272         SVCCTL_R_QUERY_SERVICE_CONFIG r_u;
273         prs_struct *data = &p->in_data.data;
274         prs_struct *rdata = &p->out_data.rdata;
275
276         ZERO_STRUCT(q_u);
277         ZERO_STRUCT(r_u);
278
279         if(!svcctl_io_q_query_service_config("", &q_u, data, 0))
280                 return False;
281
282         r_u.status = _svcctl_query_service_config(p, &q_u, &r_u);
283
284         if(!svcctl_io_r_query_service_config("", &r_u, rdata, 0))
285                 return False;
286
287         return True;
288 }
289
290 /*******************************************************************
291  ********************************************************************/
292
293 static BOOL api_svcctl_query_service_config2(pipes_struct *p)
294 {
295         SVCCTL_Q_QUERY_SERVICE_CONFIG2 q_u;
296         SVCCTL_R_QUERY_SERVICE_CONFIG2 r_u;
297         prs_struct *data = &p->in_data.data;
298         prs_struct *rdata = &p->out_data.rdata;
299
300         ZERO_STRUCT(q_u);
301         ZERO_STRUCT(r_u);
302
303         if(!svcctl_io_q_query_service_config2("", &q_u, data, 0))
304                 return False;
305
306         r_u.status = _svcctl_query_service_config2(p, &q_u, &r_u);
307
308         if(!svcctl_io_r_query_service_config2("", &r_u, rdata, 0))
309                 return False;
310
311         return True;
312 }
313
314 /*******************************************************************
315  ********************************************************************/
316
317 static BOOL api_svcctl_lock_service_db(pipes_struct *p)
318 {
319         SVCCTL_Q_LOCK_SERVICE_DB q_u;
320         SVCCTL_R_LOCK_SERVICE_DB r_u;
321         prs_struct *data = &p->in_data.data;
322         prs_struct *rdata = &p->out_data.rdata;
323
324         ZERO_STRUCT(q_u);
325         ZERO_STRUCT(r_u);
326
327         if(!svcctl_io_q_lock_service_db("", &q_u, data, 0))
328                 return False;
329
330         r_u.status = _svcctl_lock_service_db(p, &q_u, &r_u);
331
332         if(!svcctl_io_r_lock_service_db("", &r_u, rdata, 0))
333                 return False;
334
335         return True;
336 }
337
338
339 /*******************************************************************
340  ********************************************************************/
341
342 static BOOL api_svcctl_unlock_service_db(pipes_struct *p)
343 {
344         SVCCTL_Q_UNLOCK_SERVICE_DB q_u;
345         SVCCTL_R_UNLOCK_SERVICE_DB r_u;
346         prs_struct *data = &p->in_data.data;
347         prs_struct *rdata = &p->out_data.rdata;
348
349         ZERO_STRUCT(q_u);
350         ZERO_STRUCT(r_u);
351
352         if(!svcctl_io_q_unlock_service_db("", &q_u, data, 0))
353                 return False;
354
355         r_u.status = _svcctl_unlock_service_db(p, &q_u, &r_u);
356
357         if(!svcctl_io_r_unlock_service_db("", &r_u, rdata, 0))
358                 return False;
359
360         return True;
361 }
362
363 /*******************************************************************
364  ********************************************************************/
365
366 static BOOL api_svcctl_query_security_sec(pipes_struct *p)
367 {
368         SVCCTL_Q_QUERY_SERVICE_SEC q_u;
369         SVCCTL_R_QUERY_SERVICE_SEC r_u;
370         prs_struct *data = &p->in_data.data;
371         prs_struct *rdata = &p->out_data.rdata;
372
373         ZERO_STRUCT(q_u);
374         ZERO_STRUCT(r_u);
375
376         if(!svcctl_io_q_query_service_sec("", &q_u, data, 0))
377                 return False;
378
379         r_u.status = _svcctl_query_service_sec(p, &q_u, &r_u);
380
381         if(!svcctl_io_r_query_service_sec("", &r_u, rdata, 0))
382                 return False;
383
384         return True;
385 }
386
387 /*******************************************************************
388  ********************************************************************/
389
390 static BOOL api_svcctl_set_security_sec(pipes_struct *p)
391 {
392         SVCCTL_Q_SET_SERVICE_SEC q_u;
393         SVCCTL_R_SET_SERVICE_SEC r_u;
394         prs_struct *data = &p->in_data.data;
395         prs_struct *rdata = &p->out_data.rdata;
396
397         ZERO_STRUCT(q_u);
398         ZERO_STRUCT(r_u);
399
400         if(!svcctl_io_q_set_service_sec("", &q_u, data, 0))
401                 return False;
402
403         r_u.status = _svcctl_set_service_sec(p, &q_u, &r_u);
404
405         if(!svcctl_io_r_set_service_sec("", &r_u, rdata, 0))
406                 return False;
407
408         return True;
409 }
410
411
412 /*******************************************************************
413  \PIPE\svcctl commands
414  ********************************************************************/
415
416 static struct api_struct api_svcctl_cmds[] =
417 {
418       { "SVCCTL_CLOSE_SERVICE"              , SVCCTL_CLOSE_SERVICE              , api_svcctl_close_service },
419       { "SVCCTL_OPEN_SCMANAGER_W"           , SVCCTL_OPEN_SCMANAGER_W           , api_svcctl_open_scmanager },
420       { "SVCCTL_OPEN_SERVICE_W"             , SVCCTL_OPEN_SERVICE_W             , api_svcctl_open_service },
421       { "SVCCTL_GET_DISPLAY_NAME"           , SVCCTL_GET_DISPLAY_NAME           , api_svcctl_get_display_name },
422       { "SVCCTL_QUERY_STATUS"               , SVCCTL_QUERY_STATUS               , api_svcctl_query_status },
423       { "SVCCTL_QUERY_SERVICE_CONFIG_W"     , SVCCTL_QUERY_SERVICE_CONFIG_W     , api_svcctl_query_service_config },
424       { "SVCCTL_QUERY_SERVICE_CONFIG2_W"    , SVCCTL_QUERY_SERVICE_CONFIG2_W    , api_svcctl_query_service_config2 },
425       { "SVCCTL_ENUM_SERVICES_STATUS_W"     , SVCCTL_ENUM_SERVICES_STATUS_W     , api_svcctl_enum_services_status },
426       { "SVCCTL_ENUM_DEPENDENT_SERVICES_W"  , SVCCTL_ENUM_DEPENDENT_SERVICES_W  , api_svcctl_enum_dependent_services },
427       { "SVCCTL_START_SERVICE_W"            , SVCCTL_START_SERVICE_W            , api_svcctl_start_service },
428       { "SVCCTL_CONTROL_SERVICE"            , SVCCTL_CONTROL_SERVICE            , api_svcctl_control_service },
429       { "SVCCTL_QUERY_SERVICE_STATUSEX_W"   , SVCCTL_QUERY_SERVICE_STATUSEX_W   , api_svcctl_query_service_status_ex },
430       { "SVCCTL_LOCK_SERVICE_DB"            , SVCCTL_LOCK_SERVICE_DB            , api_svcctl_lock_service_db },
431       { "SVCCTL_UNLOCK_SERVICE_DB"          , SVCCTL_UNLOCK_SERVICE_DB          , api_svcctl_unlock_service_db },
432       { "SVCCTL_QUERY_SERVICE_SEC"          , SVCCTL_QUERY_SERVICE_SEC          , api_svcctl_query_security_sec },
433       { "SVCCTL_SET_SERVICE_SEC"            , SVCCTL_SET_SERVICE_SEC            , api_svcctl_set_security_sec }
434 };
435
436
437 void svcctl2_get_pipe_fns( struct api_struct **fns, int *n_fns )
438 {
439         *fns = api_svcctl_cmds;
440         *n_fns = sizeof(api_svcctl_cmds) / sizeof(struct api_struct);
441 }
442
443 NTSTATUS rpc_svcctl2_init(void)
444 {
445         return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
446                                           "svcctl", "ntsvcs", api_svcctl_cmds,
447                                           sizeof(api_svcctl_cmds) / sizeof(struct api_struct));
448 }