further abstraction involving client states. main client-side code
[kai/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_connection *con = NULL;
47
48         if (!cli_connection_init(srv_name, PIPE_SVCCTL, &con))
49         {
50                 return False;
51         }
52
53         if (hnd == NULL) return False;
54
55         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
56         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
57
58         /* create and send a MSRPC command with api SVC_OPEN_SC_MAN */
59
60         DEBUG(4,("SVC Open SC_MAN\n"));
61
62         make_svc_q_open_sc_man(&q_o, srv_name, db_name, des_access);
63
64         /* turn parameters into data stream */
65         svc_io_q_open_sc_man("", &q_o, &buf, 0);
66
67         /* send the data on \PIPE\ */
68         if (rpc_con_pipe_req(con, SVC_OPEN_SC_MAN, &buf, &rbuf))
69         {
70                 SVC_R_OPEN_SC_MAN r_o;
71                 BOOL p;
72
73                 ZERO_STRUCT(r_o);
74
75                 svc_io_r_open_sc_man("", &r_o, &rbuf, 0);
76                 p = rbuf.offset != 0;
77
78                 if (p && r_o.status != 0)
79                 {
80                         /* report error code */
81                         DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
82                         p = False;
83                 }
84
85                 if (p)
86                 {
87                         /* ok, at last: we're happy. return the policy handle */
88                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
89                         valid_pol = True;
90                         valid_pol = register_policy_hnd(hnd) &&
91                                     set_policy_con(hnd, con, 
92                                                          cli_connection_unlink);
93                 }
94         }
95
96         prs_mem_free(&rbuf);
97         prs_mem_free(&buf );
98
99         return valid_pol;
100 }
101
102
103 /****************************************************************************
104 do a SVC Open Service
105 ****************************************************************************/
106 BOOL svc_open_service( POLICY_HND *scm_hnd,
107                                 const char *srv_name,
108                                 uint32 des_access,
109                                 POLICY_HND *hnd)
110 {
111         prs_struct rbuf;
112         prs_struct buf; 
113         SVC_Q_OPEN_SERVICE q_o;
114         BOOL valid_pol = False;
115
116         struct cli_connection *con = NULL;
117
118         if (!cli_connection_get(scm_hnd, &con))
119         {
120                 return False;
121         }
122
123         if (hnd == NULL || scm_hnd == NULL) return False;
124
125         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
126         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
127
128         /* create and send a MSRPC command with api SVC_OPEN_SERVICE */
129
130         DEBUG(4,("SVC Open Service\n"));
131
132         make_svc_q_open_service(&q_o, scm_hnd, srv_name, des_access);
133
134         /* turn parameters into data stream */
135         svc_io_q_open_service("", &q_o, &buf, 0);
136
137         /* send the data on \PIPE\ */
138         if (rpc_con_pipe_req(con, SVC_OPEN_SERVICE, &buf, &rbuf))
139         {
140                 SVC_R_OPEN_SERVICE r_o;
141                 BOOL p;
142
143                 ZERO_STRUCT(r_o);
144
145                 svc_io_r_open_service("", &r_o, &rbuf, 0);
146                 p = rbuf.offset != 0;
147
148                 if (p && r_o.status != 0)
149                 {
150                         /* report error code */
151                         DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
152                         p = False;
153                 }
154
155                 if (p)
156                 {
157                         /* ok, at last: we're happy. return the policy handle */
158                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
159                         valid_pol = register_policy_hnd(hnd) &&
160                                     set_policy_con(hnd, con, NULL);
161                 }
162         }
163
164         prs_mem_free(&rbuf);
165         prs_mem_free(&buf );
166
167         return valid_pol;
168 }
169
170
171 /****************************************************************************
172 do a SVC Enumerate Services
173 ****************************************************************************/
174 BOOL svc_enum_svcs( POLICY_HND *hnd,
175                                 uint32 services_type, uint32 services_state,
176                                 uint32 *buf_size, uint32 *resume_hnd,
177                                 uint32 *dos_error,
178                                 ENUM_SRVC_STATUS **svcs, uint32 *num_svcs)
179 {
180         prs_struct rbuf;
181         prs_struct buf; 
182         SVC_Q_ENUM_SVCS_STATUS q_o;
183         BOOL valid_pol = False;
184
185         struct cli_connection *con = NULL;
186
187         if (!cli_connection_get(hnd, &con))
188         {
189                 return False;
190         }
191
192         if (hnd == NULL || buf_size == NULL || dos_error == NULL || num_svcs == NULL)
193         {
194                 return False;
195         }
196
197         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
198         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
199
200         /* create and send a MSRPC command with api SVC_ENUM_SVCS_STATUS */
201
202         DEBUG(4,("SVC Enum Services Status\n"));
203
204         make_svc_q_enum_svcs_status(&q_o, hnd,
205                                     services_type, services_state,
206                                     *buf_size, *resume_hnd);
207
208         /* turn parameters into data stream */
209         svc_io_q_enum_svcs_status("", &q_o, &buf, 0);
210
211         /* send the data on \PIPE\ */
212         if (rpc_con_pipe_req(con, SVC_ENUM_SVCS_STATUS, &buf, &rbuf))
213         {
214                 SVC_R_ENUM_SVCS_STATUS r_o;
215                 BOOL p;
216
217                 ZERO_STRUCT(r_o);
218
219                 svc_io_r_enum_svcs_status("", &r_o, &rbuf, 0);
220                 p = rbuf.offset != 0;
221
222                 if (p && r_o.dos_status != 0)
223                 {
224                         fstring errmsg;
225
226                         if (r_o.dos_status != ERRmoredata)
227                         {
228                                 smb_safe_err_msg(ERRDOS, r_o.dos_status,
229                                                  errmsg, sizeof(errmsg));
230                                 /* report error code */
231                                 DEBUG(1,("SVC_ENUM_SVCS_STATUS: %s\n", errmsg));
232                         }
233                         p = r_o.dos_status == ERRmoredata;
234                 }
235
236                 if (p)
237                 {
238                         (*svcs) = r_o.svcs;
239                         (*num_svcs) = r_o.num_svcs;
240                         (*resume_hnd) = get_enum_hnd(&r_o.resume_hnd);
241                         (*buf_size) = r_o.more_buf_size;
242                         (*dos_error) = r_o.dos_status;
243                         valid_pol = True;
244                 }
245         }
246
247         prs_mem_free(&rbuf);
248         prs_mem_free(&buf );
249
250         return valid_pol;
251 }
252
253
254 /****************************************************************************
255 do a SVC Stop Service 
256 ****************************************************************************/
257 BOOL svc_stop_service( POLICY_HND *hnd,
258                                 uint32 unknown)
259 {
260         prs_struct rbuf;
261         prs_struct buf; 
262         SVC_Q_STOP_SERVICE q_c;
263         BOOL valid_cfg = False;
264
265         struct cli_connection *con = NULL;
266
267         if (!cli_connection_get(hnd, &con))
268         {
269                 return False;
270         }
271
272         if (hnd == NULL) return False;
273
274         /* create and send a MSRPC command with api SVC_STOP_SERVICE */
275
276         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
277         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
278
279         DEBUG(4,("SVC Stop Service\n"));
280
281         /* store the parameters */
282         make_svc_q_stop_service(&q_c, hnd, unknown);
283
284         /* turn parameters into data stream */
285         svc_io_q_stop_service("", &q_c, &buf, 0);
286
287         /* send the data on \PIPE\ */
288         if (rpc_con_pipe_req(con, SVC_STOP_SERVICE, &buf, &rbuf))
289         {
290                 SVC_R_STOP_SERVICE r_c;
291                 BOOL p;
292
293                 ZERO_STRUCT (r_c);
294
295                 svc_io_r_stop_service("", &r_c, &rbuf, 0);
296                 p = rbuf.offset != 0;
297
298                 if (p && r_c.status != 0)
299                 {
300                         /* report error code */
301                         DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
302                         p = False;
303                 }
304
305                 if (p)
306                 {
307                         valid_cfg = True;
308                 }
309         }
310
311         prs_mem_free(&rbuf);
312         prs_mem_free(&buf );
313
314         return valid_cfg;
315 }
316
317
318 /****************************************************************************
319 do a SVC Start Service 
320 ****************************************************************************/
321 BOOL svc_start_service( POLICY_HND *hnd,
322                                 uint32 argc,
323                                 char **argv)
324 {
325         prs_struct rbuf;
326         prs_struct buf; 
327         SVC_Q_START_SERVICE q_c;
328         BOOL valid_cfg = False;
329
330         struct cli_connection *con = NULL;
331
332         if (!cli_connection_get(hnd, &con))
333         {
334                 return False;
335         }
336
337         if (hnd == NULL) return False;
338
339         /* create and send a MSRPC command with api SVC_START_SERVICE */
340
341         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
342         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
343
344         DEBUG(4,("SVC Start Service\n"));
345
346         /* store the parameters */
347         make_svc_q_start_service(&q_c, hnd, argc, argv);
348
349         /* turn parameters into data stream */
350         svc_io_q_start_service("", &q_c, &buf, 0);
351
352         /* send the data on \PIPE\ */
353         if (rpc_con_pipe_req(con, SVC_START_SERVICE, &buf, &rbuf))
354         {
355                 SVC_R_START_SERVICE r_c;
356                 BOOL p;
357
358                 ZERO_STRUCT (r_c);
359
360                 svc_io_r_start_service("", &r_c, &rbuf, 0);
361                 p = rbuf.offset != 0;
362
363                 if (p && r_c.status != 0)
364                 {
365                         /* report error code */
366                         DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
367                         p = False;
368                 }
369
370                 if (p)
371                 {
372                         valid_cfg = True;
373                 }
374         }
375
376         prs_mem_free(&rbuf);
377         prs_mem_free(&buf );
378
379         return valid_cfg;
380 }
381
382
383 /****************************************************************************
384 do a SVC Query Service Config
385 ****************************************************************************/
386 BOOL svc_query_svc_cfg( POLICY_HND *hnd,
387                                 QUERY_SERVICE_CONFIG *cfg,
388                                 uint32 *buf_size)
389 {
390         prs_struct rbuf;
391         prs_struct buf; 
392         SVC_Q_QUERY_SVC_CONFIG q_c;
393         BOOL valid_cfg = False;
394
395         struct cli_connection *con = NULL;
396
397         if (!cli_connection_get(hnd, &con))
398         {
399                 return False;
400         }
401
402         if (hnd == NULL || buf_size == NULL) return False;
403
404         /* create and send a MSRPC command with api SVC_QUERY_SVC_CONFIG */
405
406         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
407         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
408
409         DEBUG(4,("SVC Query Service Config\n"));
410
411         /* store the parameters */
412         make_svc_q_query_svc_config(&q_c, hnd, *buf_size);
413
414         /* turn parameters into data stream */
415         svc_io_q_query_svc_config("", &q_c, &buf, 0);
416
417         /* send the data on \PIPE\ */
418         if (rpc_con_pipe_req(con, SVC_QUERY_SVC_CONFIG, &buf, &rbuf))
419         {
420                 SVC_R_QUERY_SVC_CONFIG r_c;
421                 BOOL p;
422
423                 ZERO_STRUCT (r_c);
424                 ZERO_STRUCTP(cfg);
425
426                 r_c.cfg = cfg;
427
428                 svc_io_r_query_svc_config("", &r_c, &rbuf, 0);
429                 p = rbuf.offset != 0;
430
431                 if (p && r_c.status != 0)
432                 {
433                         /* report error code */
434                         DEBUG(1,("SVC_QUERY_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
435                         p = False;
436                 }
437
438                 if (p)
439                 {
440                         valid_cfg = r_c.buf_size != 0;
441                 }
442         }
443
444         prs_mem_free(&rbuf);
445         prs_mem_free(&buf );
446
447         return valid_cfg;
448 }
449
450
451 /****************************************************************************
452 do a SVC Close
453 ****************************************************************************/
454 BOOL svc_close(POLICY_HND *hnd)
455 {
456         prs_struct rbuf;
457         prs_struct buf; 
458         SVC_Q_CLOSE q_c;
459         BOOL valid_close = False;
460
461         struct cli_connection *con = NULL;
462
463         if (!cli_connection_get(hnd, &con))
464         {
465                 return False;
466         }
467
468         if (hnd == NULL) return False;
469
470         /* create and send a MSRPC command with api SVC_CLOSE */
471
472         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
473         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
474
475         DEBUG(4,("SVC Close\n"));
476
477         /* store the parameters */
478         make_svc_q_close(&q_c, hnd);
479
480         /* turn parameters into data stream */
481         svc_io_q_close("", &q_c, &buf, 0);
482
483         /* send the data on \PIPE\ */
484         if (rpc_con_pipe_req(con, SVC_CLOSE, &buf, &rbuf))
485         {
486                 SVC_R_CLOSE r_c;
487                 BOOL p;
488
489                 ZERO_STRUCT(r_c);
490
491                 svc_io_r_close("", &r_c, &rbuf, 0);
492                 p = rbuf.offset != 0;
493
494                 if (p && r_c.status != 0)
495                 {
496                         /* report error code */
497                         DEBUG(1,("SVC_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
498                         p = False;
499                 }
500
501                 if (p)
502                 {
503                         /* check that the returned policy handle is all zeros */
504                         uint32 i;
505                         valid_close = True;
506
507                         for (i = 0; i < sizeof(r_c.pol.data); i++)
508                         {
509                                 if (r_c.pol.data[i] != 0)
510                                 {
511                                         valid_close = False;
512                                         break;
513                                 }
514                         }       
515                         if (!valid_close)
516                         {
517                                 DEBUG(1,("SVC_CLOSE: non-zero handle returned\n"));
518                         }
519                 }
520         }
521
522         close_policy_hnd(hnd);
523
524         prs_mem_free(&rbuf);
525         prs_mem_free(&buf );
526
527         return valid_close;
528 }
529
530 /****************************************************************************
531 do a SVC Change Service Config
532 ****************************************************************************/
533 BOOL svc_change_svc_cfg( POLICY_HND *hnd,
534                                 uint32 service_type, uint32 start_type,
535                                 uint32 unknown_0,
536                                 uint32 error_control,
537                                 char* bin_path_name, char* load_order_grp, 
538                                 uint32 tag_id,
539                                 char* dependencies, char* service_start_name,
540                                 char* password,
541                                 char* disp_name)
542 {
543         prs_struct rbuf;
544         prs_struct buf; 
545         SVC_Q_CHANGE_SVC_CONFIG q_c;
546         BOOL valid_cfg = False;
547
548         struct cli_connection *con = NULL;
549
550         if (!cli_connection_get(hnd, &con))
551         {
552                 return False;
553         }
554
555         if (hnd == NULL) return False;
556
557         /* create and send a MSRPC command with api SVC_CHANGE_SVC_CONFIG */
558
559         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
560         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
561
562         DEBUG(4,("SVC Change Service Config\n"));
563
564         /* store the parameters */
565         make_svc_q_change_svc_config(&q_c, hnd, 
566                                 service_type, start_type,
567                                 unknown_0, error_control,
568                                 bin_path_name, load_order_grp, 
569                                 tag_id,
570                                 dependencies, service_start_name,
571                                 password, disp_name);
572
573         /* turn parameters into data stream */
574         svc_io_q_change_svc_config("", &q_c, &buf, 0);
575
576         /* send the data on \PIPE\ */
577         if (rpc_con_pipe_req(con, SVC_CHANGE_SVC_CONFIG, &buf, &rbuf))
578         {
579                 SVC_R_CHANGE_SVC_CONFIG r_c;
580                 BOOL p;
581
582                 ZERO_STRUCT (r_c);
583
584                 svc_io_r_change_svc_config("", &r_c, &rbuf, 0);
585                 p = rbuf.offset != 0;
586
587                 if (p && r_c.status != 0)
588                 {
589                         /* report error code */
590                         DEBUG(1,("SVC_CHANGE_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
591                         p = False;
592                 }
593
594                 if (p)
595                 {
596                         valid_cfg = True;
597                 }
598         }
599
600         prs_mem_free(&rbuf);
601         prs_mem_free(&buf );
602
603         return valid_cfg;
604 }