service control manager API completed. svcenum -i works, but does not
[vlendec/samba-autobuild/.git] / source3 / rpc_client / cli_svcctl.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1998,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                  1997-1998.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33
34 /****************************************************************************
35 do a SVC Open Policy
36 ****************************************************************************/
37 BOOL svc_open_sc_man( const char *srv_name, char *db_name,
38                                 uint32 des_access,
39                                 POLICY_HND *hnd)
40 {
41         prs_struct rbuf;
42         prs_struct buf; 
43         SVC_Q_OPEN_SC_MAN q_o;
44         BOOL valid_pol = False;
45
46         struct cli_state *cli = NULL;
47         uint16 fnum = 0xffff;
48
49         if (!cli_state_init(srv_name, PIPE_SVCCTL, &cli, &fnum))
50         {
51                 return False;
52         }
53
54         if (hnd == NULL) return False;
55
56         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
57         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
58
59         /* create and send a MSRPC command with api SVC_OPEN_SC_MAN */
60
61         DEBUG(4,("SVC Open SC_MAN\n"));
62
63         make_svc_q_open_sc_man(&q_o, srv_name, db_name, des_access);
64
65         /* turn parameters into data stream */
66         svc_io_q_open_sc_man("", &q_o, &buf, 0);
67
68         /* send the data on \PIPE\ */
69         if (rpc_api_pipe_req(cli, fnum, SVC_OPEN_SC_MAN, &buf, &rbuf))
70         {
71                 SVC_R_OPEN_SC_MAN r_o;
72                 BOOL p;
73
74                 ZERO_STRUCT(r_o);
75
76                 svc_io_r_open_sc_man("", &r_o, &rbuf, 0);
77                 p = rbuf.offset != 0;
78
79                 if (p && r_o.status != 0)
80                 {
81                         /* report error code */
82                         DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
83                         p = False;
84                 }
85
86                 if (p)
87                 {
88                         /* ok, at last: we're happy. return the policy handle */
89                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
90                         valid_pol = True;
91                         valid_pol = register_policy_hnd(hnd) &&
92                                     set_policy_cli_state(hnd, cli, fnum,
93                                                          cli_state_free);
94                 }
95         }
96
97         prs_mem_free(&rbuf);
98         prs_mem_free(&buf );
99
100         return valid_pol;
101 }
102
103
104 /****************************************************************************
105 do a SVC Open Service
106 ****************************************************************************/
107 BOOL svc_open_service( POLICY_HND *scm_hnd,
108                                 const char *srv_name,
109                                 uint32 des_access,
110                                 POLICY_HND *hnd)
111 {
112         prs_struct rbuf;
113         prs_struct buf; 
114         SVC_Q_OPEN_SERVICE q_o;
115         BOOL valid_pol = False;
116
117         struct cli_state *cli = NULL;
118         uint16 fnum = 0xffff;
119
120         if (!cli_state_get(scm_hnd, &cli, &fnum))
121         {
122                 return False;
123         }
124
125         if (hnd == NULL || scm_hnd == NULL) return False;
126
127         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
128         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
129
130         /* create and send a MSRPC command with api SVC_OPEN_SERVICE */
131
132         DEBUG(4,("SVC Open Service\n"));
133
134         make_svc_q_open_service(&q_o, scm_hnd, srv_name, des_access);
135
136         /* turn parameters into data stream */
137         svc_io_q_open_service("", &q_o, &buf, 0);
138
139         /* send the data on \PIPE\ */
140         if (rpc_api_pipe_req(cli, fnum, SVC_OPEN_SERVICE, &buf, &rbuf))
141         {
142                 SVC_R_OPEN_SERVICE r_o;
143                 BOOL p;
144
145                 ZERO_STRUCT(r_o);
146
147                 svc_io_r_open_service("", &r_o, &rbuf, 0);
148                 p = rbuf.offset != 0;
149
150                 if (p && r_o.status != 0)
151                 {
152                         /* report error code */
153                         DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
154                         p = False;
155                 }
156
157                 if (p)
158                 {
159                         /* ok, at last: we're happy. return the policy handle */
160                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
161                         valid_pol = register_policy_hnd(hnd) &&
162                                     set_policy_cli_state(hnd, cli, fnum,
163                                                          NULL);
164                 }
165         }
166
167         prs_mem_free(&rbuf);
168         prs_mem_free(&buf );
169
170         return valid_pol;
171 }
172
173
174 /****************************************************************************
175 do a SVC Enumerate Services
176 ****************************************************************************/
177 BOOL svc_enum_svcs( POLICY_HND *hnd,
178                                 uint32 services_type, uint32 services_state,
179                                 uint32 *buf_size, uint32 *resume_hnd,
180                                 uint32 *dos_error,
181                                 ENUM_SRVC_STATUS **svcs, uint32 *num_svcs)
182 {
183         prs_struct rbuf;
184         prs_struct buf; 
185         SVC_Q_ENUM_SVCS_STATUS q_o;
186         BOOL valid_pol = False;
187
188         struct cli_state *cli = NULL;
189         uint16 fnum = 0xffff;
190
191         if (!cli_state_get(hnd, &cli, &fnum))
192         {
193                 return False;
194         }
195
196         if (hnd == NULL || buf_size == NULL || dos_error == NULL || num_svcs == NULL)
197         {
198                 return False;
199         }
200
201         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
202         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
203
204         /* create and send a MSRPC command with api SVC_ENUM_SVCS_STATUS */
205
206         DEBUG(4,("SVC Enum Services Status\n"));
207
208         make_svc_q_enum_svcs_status(&q_o, hnd,
209                                     services_type, services_state,
210                                     *buf_size, *resume_hnd);
211
212         /* turn parameters into data stream */
213         svc_io_q_enum_svcs_status("", &q_o, &buf, 0);
214
215         /* send the data on \PIPE\ */
216         if (rpc_api_pipe_req(cli, fnum, SVC_ENUM_SVCS_STATUS, &buf, &rbuf))
217         {
218                 SVC_R_ENUM_SVCS_STATUS r_o;
219                 BOOL p;
220
221                 ZERO_STRUCT(r_o);
222
223                 svc_io_r_enum_svcs_status("", &r_o, &rbuf, 0);
224                 p = rbuf.offset != 0;
225
226                 if (p && r_o.dos_status != 0)
227                 {
228                         fstring errmsg;
229
230                         if (r_o.dos_status != ERRmoredata)
231                         {
232                                 smb_safe_err_msg(ERRDOS, r_o.dos_status,
233                                                  errmsg, sizeof(errmsg));
234                                 /* report error code */
235                                 DEBUG(1,("SVC_ENUM_SVCS_STATUS: %s\n", errmsg));
236                         }
237                         p = r_o.dos_status == ERRmoredata;
238                 }
239
240                 if (p)
241                 {
242                         (*svcs) = r_o.svcs;
243                         (*num_svcs) = r_o.num_svcs;
244                         (*resume_hnd) = get_enum_hnd(&r_o.resume_hnd);
245                         (*buf_size) = r_o.more_buf_size;
246                         (*dos_error) = r_o.dos_status;
247                         valid_pol = True;
248                 }
249         }
250
251         prs_mem_free(&rbuf);
252         prs_mem_free(&buf );
253
254         return valid_pol;
255 }
256
257
258 /****************************************************************************
259 do a SVC Stop Service 
260 ****************************************************************************/
261 BOOL svc_stop_service( POLICY_HND *hnd,
262                                 uint32 unknown)
263 {
264         prs_struct rbuf;
265         prs_struct buf; 
266         SVC_Q_STOP_SERVICE q_c;
267         BOOL valid_cfg = False;
268
269         struct cli_state *cli = NULL;
270         uint16 fnum = 0xffff;
271
272         if (!cli_state_get(hnd, &cli, &fnum))
273         {
274                 return False;
275         }
276
277         if (hnd == NULL) return False;
278
279         /* create and send a MSRPC command with api SVC_STOP_SERVICE */
280
281         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
282         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
283
284         DEBUG(4,("SVC Stop Service\n"));
285
286         /* store the parameters */
287         make_svc_q_stop_service(&q_c, hnd, unknown);
288
289         /* turn parameters into data stream */
290         svc_io_q_stop_service("", &q_c, &buf, 0);
291
292         /* send the data on \PIPE\ */
293         if (rpc_api_pipe_req(cli, fnum, SVC_STOP_SERVICE, &buf, &rbuf))
294         {
295                 SVC_R_STOP_SERVICE r_c;
296                 BOOL p;
297
298                 ZERO_STRUCT (r_c);
299
300                 svc_io_r_stop_service("", &r_c, &rbuf, 0);
301                 p = rbuf.offset != 0;
302
303                 if (p && r_c.status != 0)
304                 {
305                         /* report error code */
306                         DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
307                         p = False;
308                 }
309
310                 if (p)
311                 {
312                         valid_cfg = True;
313                 }
314         }
315
316         prs_mem_free(&rbuf);
317         prs_mem_free(&buf );
318
319         return valid_cfg;
320 }
321
322
323 /****************************************************************************
324 do a SVC Start Service 
325 ****************************************************************************/
326 BOOL svc_start_service( POLICY_HND *hnd,
327                                 uint32 argc,
328                                 char **argv)
329 {
330         prs_struct rbuf;
331         prs_struct buf; 
332         SVC_Q_START_SERVICE q_c;
333         BOOL valid_cfg = False;
334
335         struct cli_state *cli = NULL;
336         uint16 fnum = 0xffff;
337
338         if (!cli_state_get(hnd, &cli, &fnum))
339         {
340                 return False;
341         }
342
343         if (hnd == NULL) return False;
344
345         /* create and send a MSRPC command with api SVC_START_SERVICE */
346
347         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
348         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
349
350         DEBUG(4,("SVC Start Service\n"));
351
352         /* store the parameters */
353         make_svc_q_start_service(&q_c, hnd, argc, argv);
354
355         /* turn parameters into data stream */
356         svc_io_q_start_service("", &q_c, &buf, 0);
357
358         /* send the data on \PIPE\ */
359         if (rpc_api_pipe_req(cli, fnum, SVC_START_SERVICE, &buf, &rbuf))
360         {
361                 SVC_R_START_SERVICE r_c;
362                 BOOL p;
363
364                 ZERO_STRUCT (r_c);
365
366                 svc_io_r_start_service("", &r_c, &rbuf, 0);
367                 p = rbuf.offset != 0;
368
369                 if (p && r_c.status != 0)
370                 {
371                         /* report error code */
372                         DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
373                         p = False;
374                 }
375
376                 if (p)
377                 {
378                         valid_cfg = True;
379                 }
380         }
381
382         prs_mem_free(&rbuf);
383         prs_mem_free(&buf );
384
385         return valid_cfg;
386 }
387
388
389 /****************************************************************************
390 do a SVC Query Service Config
391 ****************************************************************************/
392 BOOL svc_query_svc_cfg( POLICY_HND *hnd,
393                                 QUERY_SERVICE_CONFIG *cfg,
394                                 uint32 *buf_size)
395 {
396         prs_struct rbuf;
397         prs_struct buf; 
398         SVC_Q_QUERY_SVC_CONFIG q_c;
399         BOOL valid_cfg = False;
400
401         struct cli_state *cli = NULL;
402         uint16 fnum = 0xffff;
403
404         if (!cli_state_get(hnd, &cli, &fnum))
405         {
406                 return False;
407         }
408
409         if (hnd == NULL || buf_size == NULL) return False;
410
411         /* create and send a MSRPC command with api SVC_QUERY_SVC_CONFIG */
412
413         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
414         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
415
416         DEBUG(4,("SVC Query Service Config\n"));
417
418         /* store the parameters */
419         make_svc_q_query_svc_config(&q_c, hnd, *buf_size);
420
421         /* turn parameters into data stream */
422         svc_io_q_query_svc_config("", &q_c, &buf, 0);
423
424         /* send the data on \PIPE\ */
425         if (rpc_api_pipe_req(cli, fnum, SVC_QUERY_SVC_CONFIG, &buf, &rbuf))
426         {
427                 SVC_R_QUERY_SVC_CONFIG r_c;
428                 BOOL p;
429
430                 ZERO_STRUCT (r_c);
431                 ZERO_STRUCTP(cfg);
432
433                 r_c.cfg = cfg;
434
435                 svc_io_r_query_svc_config("", &r_c, &rbuf, 0);
436                 p = rbuf.offset != 0;
437
438                 if (p && r_c.status != 0)
439                 {
440                         /* report error code */
441                         DEBUG(1,("SVC_QUERY_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
442                         p = False;
443                 }
444
445                 if (p)
446                 {
447                         valid_cfg = r_c.buf_size != 0;
448                 }
449         }
450
451         prs_mem_free(&rbuf);
452         prs_mem_free(&buf );
453
454         return valid_cfg;
455 }
456
457
458 /****************************************************************************
459 do a SVC Close
460 ****************************************************************************/
461 BOOL svc_close(POLICY_HND *hnd)
462 {
463         prs_struct rbuf;
464         prs_struct buf; 
465         SVC_Q_CLOSE q_c;
466         BOOL valid_close = False;
467
468         struct cli_state *cli = NULL;
469         uint16 fnum = 0xffff;
470
471         if (!cli_state_get(hnd, &cli, &fnum))
472         {
473                 return False;
474         }
475
476         if (hnd == NULL) return False;
477
478         /* create and send a MSRPC command with api SVC_CLOSE */
479
480         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
481         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
482
483         DEBUG(4,("SVC Close\n"));
484
485         /* store the parameters */
486         make_svc_q_close(&q_c, hnd);
487
488         /* turn parameters into data stream */
489         svc_io_q_close("", &q_c, &buf, 0);
490
491         /* send the data on \PIPE\ */
492         if (rpc_api_pipe_req(cli, fnum, SVC_CLOSE, &buf, &rbuf))
493         {
494                 SVC_R_CLOSE r_c;
495                 BOOL p;
496
497                 ZERO_STRUCT(r_c);
498
499                 svc_io_r_close("", &r_c, &rbuf, 0);
500                 p = rbuf.offset != 0;
501
502                 if (p && r_c.status != 0)
503                 {
504                         /* report error code */
505                         DEBUG(1,("SVC_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
506                         p = False;
507                 }
508
509                 if (p)
510                 {
511                         /* check that the returned policy handle is all zeros */
512                         uint32 i;
513                         valid_close = True;
514
515                         for (i = 0; i < sizeof(r_c.pol.data); i++)
516                         {
517                                 if (r_c.pol.data[i] != 0)
518                                 {
519                                         valid_close = False;
520                                         break;
521                                 }
522                         }       
523                         if (!valid_close)
524                         {
525                                 DEBUG(1,("SVC_CLOSE: non-zero handle returned\n"));
526                         }
527                 }
528         }
529
530         close_policy_hnd(hnd);
531
532         prs_mem_free(&rbuf);
533         prs_mem_free(&buf );
534
535         return valid_close;
536 }
537
538 /****************************************************************************
539 do a SVC Change Service Config
540 ****************************************************************************/
541 BOOL svc_change_svc_cfg( POLICY_HND *hnd,
542                                 uint32 service_type, uint32 start_type,
543                                 uint32 unknown_0,
544                                 uint32 error_control,
545                                 char* bin_path_name, char* load_order_grp, 
546                                 uint32 tag_id,
547                                 char* dependencies, char* service_start_name,
548                                 char* password,
549                                 char* disp_name)
550 {
551         prs_struct rbuf;
552         prs_struct buf; 
553         SVC_Q_CHANGE_SVC_CONFIG q_c;
554         BOOL valid_cfg = False;
555
556         struct cli_state *cli = NULL;
557         uint16 fnum = 0xffff;
558
559         if (!cli_state_get(hnd, &cli, &fnum))
560         {
561                 return False;
562         }
563
564         if (hnd == NULL) return False;
565
566         /* create and send a MSRPC command with api SVC_CHANGE_SVC_CONFIG */
567
568         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
569         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
570
571         DEBUG(4,("SVC Change Service Config\n"));
572
573         /* store the parameters */
574         make_svc_q_change_svc_config(&q_c, hnd, 
575                                 service_type, start_type,
576                                 unknown_0, error_control,
577                                 bin_path_name, load_order_grp, 
578                                 tag_id,
579                                 dependencies, service_start_name,
580                                 password, disp_name);
581
582         /* turn parameters into data stream */
583         svc_io_q_change_svc_config("", &q_c, &buf, 0);
584
585         /* send the data on \PIPE\ */
586         if (rpc_api_pipe_req(cli, fnum, SVC_CHANGE_SVC_CONFIG, &buf, &rbuf))
587         {
588                 SVC_R_CHANGE_SVC_CONFIG r_c;
589                 BOOL p;
590
591                 ZERO_STRUCT (r_c);
592
593                 svc_io_r_change_svc_config("", &r_c, &rbuf, 0);
594                 p = rbuf.offset != 0;
595
596                 if (p && r_c.status != 0)
597                 {
598                         /* report error code */
599                         DEBUG(1,("SVC_CHANGE_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
600                         p = False;
601                 }
602
603                 if (p)
604                 {
605                         valid_cfg = True;
606                 }
607         }
608
609         prs_mem_free(&rbuf);
610         prs_mem_free(&buf );
611
612         return valid_cfg;
613 }