service control manager API completed. svcenum -i works, but does not
[metze/samba/wip.git] / source3 / rpcclient / cmd_svcctl.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24
25 #ifdef SYSLOG
26 #undef SYSLOG
27 #endif
28
29 #include "includes.h"
30 #include "nterr.h"
31
32 extern int DEBUGLEVEL;
33
34 extern FILE* out_hnd;
35
36 void svc_display_query_svc_cfg(const QUERY_SERVICE_CONFIG *cfg)
37 {
38         display_query_svc_cfg(out_hnd, ACTION_HEADER   , cfg);
39         display_query_svc_cfg(out_hnd, ACTION_ENUMERATE, cfg);
40         display_query_svc_cfg(out_hnd, ACTION_FOOTER   , cfg);
41 }
42
43 BOOL svc_query_service( POLICY_HND *pol_scm,
44                                 const char *svc_name,
45                                 SVC_QUERY_FN(svc_query_fn))
46 {
47         BOOL res2 = True;
48         BOOL res3;
49         POLICY_HND pol_svc;
50         QUERY_SERVICE_CONFIG cfg;
51         uint32 svc_buf_size = 0x8000;
52
53         res2 = res2 ? svc_open_service( pol_scm,
54                                        svc_name, 0x80000001,
55                                        &pol_svc) : False;
56         res3 = res2 ? svc_query_svc_cfg( &pol_svc, &cfg,
57                                        &svc_buf_size) : False;
58
59         if (res3 && svc_query_fn != NULL)
60         {
61                 svc_query_fn(&cfg);
62         }
63
64         res2 = res2 ? svc_close(&pol_svc) : False;
65
66         return res3;
67 }
68
69 /****************************************************************************
70 nt service info
71 ****************************************************************************/
72 void cmd_svc_info(struct client_info *info, int argc, char *argv[])
73 {
74         BOOL res = True;
75         BOOL res1 = True;
76         char *svc_name;
77
78         POLICY_HND pol_scm;
79         
80         fstring srv_name;
81
82         fstrcpy(srv_name, "\\\\");
83         fstrcat(srv_name, info->dest_host);
84         strupper(srv_name);
85
86         DEBUG(4,("cmd_svc_info: server:%s\n", srv_name));
87
88         if (argc < 2)
89         {
90                 report(out_hnd,"svcinfo <service name>\n");
91                 return;
92         }
93
94         svc_name = argv[1];
95
96         /* open service control manager receive a policy handle */
97         res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
98                                 &pol_scm) : False;
99
100         res1 = svc_query_service(&pol_scm, svc_name,
101                                 svc_display_query_svc_cfg);
102
103         res = res ? svc_close(&pol_scm) : False;
104
105         if (res && res1)
106         {
107                 DEBUG(5,("cmd_svc_info: query succeeded\n"));
108         }
109         else
110         {
111                 DEBUG(5,("cmd_svc_info: query failed\n"));
112         }
113 }
114
115 static void svc_display_svc_info(const ENUM_SRVC_STATUS *svc)
116 {
117         display_svc_info(out_hnd, ACTION_HEADER   , svc);
118         display_svc_info(out_hnd, ACTION_ENUMERATE, svc);
119         display_svc_info(out_hnd, ACTION_FOOTER   , svc);
120 }
121
122 /****************************************************************************
123 nt service enum
124 ****************************************************************************/
125 BOOL msrpc_svc_enum(const char* srv_name,
126                                 ENUM_SRVC_STATUS **svcs,
127                                 uint32 *num_svcs,
128                                 SVC_INFO_FN(info_fn),
129                                 SVC_QUERY_FN(query_fn))
130 {
131         BOOL res = True;
132         BOOL res1 = False;
133         int i;
134         uint32 resume_hnd = 0;
135         uint32 buf_size = 0;
136         uint32 dos_error = 0;
137
138         POLICY_HND pol_scm;
139         
140         (*svcs) = NULL;
141         (*num_svcs) = 0;
142
143         /* open service control manager receive a policy handle */
144         res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
145                                 &pol_scm) : False;
146
147         do
148         {
149                 if ((*svcs) != NULL)
150                 {
151                         free(*svcs);
152                         (*svcs) = NULL;
153                         (*num_svcs) = 0;
154                 }
155
156                 buf_size += 0x800;
157
158                 /* enumerate services */
159                 res1 = res ? svc_enum_svcs( &pol_scm,
160                                         0x00000030, 0x00000003,
161                                         &buf_size, &resume_hnd, &dos_error,
162                                         svcs, num_svcs) : False;
163
164         } while (res1 && dos_error == ERRmoredata);
165
166         for (i = 0; i < (*num_svcs) && (*svcs) != NULL && res1; i++)
167         {
168                 fstring svc_name;
169
170                 unistr_to_ascii(svc_name, (*svcs)[i].uni_srvc_name.buffer,
171                                 sizeof(svc_name)-1);
172
173                 if (query_fn != NULL)
174                 {
175                         res1 = svc_query_service(&pol_scm,
176                                                  svc_name, query_fn);
177                 }
178                 else if (info_fn != NULL)
179                 {
180                         info_fn(&(*svcs)[i]);
181                 }
182         }
183
184         res = res ? svc_close(&pol_scm) : False;
185
186         return res1;
187 }
188
189 /****************************************************************************
190 nt service enum
191 ****************************************************************************/
192 void cmd_svc_enum(struct client_info *info, int argc, char *argv[])
193 {
194         ENUM_SRVC_STATUS *svcs = NULL;
195         uint32 num_svcs = 0;
196         BOOL request_info = False;
197         int opt;
198         fstring srv_name;
199
200         fstrcpy(srv_name, "\\\\");
201         fstrcat(srv_name, info->dest_host);
202         strupper(srv_name);
203
204         argc--;
205         argv++;
206
207         while ((opt = getopt(argc, argv,"i")) != EOF)
208         {
209                 switch (opt)
210                 {
211                         case 'i':
212                         {
213                                 request_info = True;
214                                 break;
215                         }
216                 }
217         }
218
219         report(out_hnd,"Services\n");
220         report(out_hnd,"--------\n");
221
222         msrpc_svc_enum(srv_name, &svcs, &num_svcs,
223                        request_info ? NULL : svc_display_svc_info,
224                        request_info ? svc_display_query_svc_cfg : NULL);
225
226         if (svcs != NULL)
227         {
228                 free(svcs);
229         }
230 }
231
232 /****************************************************************************
233 nt stop service 
234 ****************************************************************************/
235 void cmd_svc_stop(struct client_info *info, int argc, char *argv[])
236 {
237         BOOL res = True;
238         BOOL res1 = True;
239         char *svc_name;
240         BOOL res2 = True;
241         POLICY_HND pol_svc;
242         POLICY_HND pol_scm;
243         
244         fstring srv_name;
245
246         fstrcpy(srv_name, "\\\\");
247         fstrcat(srv_name, info->dest_host);
248         strupper(srv_name);
249
250         DEBUG(4,("cmd_svc_stop: server:%s\n", srv_name));
251
252         if (argc < 2)
253         {
254                 report(out_hnd,"svcstop <service name>\n");
255                 return;
256         }
257
258         svc_name = argv[1];
259
260         /* open service control manager receive a policy handle */
261         res = res ? svc_open_sc_man( srv_name, NULL, 0x80000000,
262                                 &pol_scm) : False;
263
264         res1 = res ? svc_open_service( &pol_scm,
265                                        svc_name, 0x00000020,
266                                        &pol_svc) : False;
267         res2 = res1 ? svc_stop_service(&pol_svc, 0x1) : False;
268
269         res1 = res1 ? svc_close(&pol_svc) : False;
270         res  = res  ? svc_close(&pol_scm) : False;
271
272         if (res2)
273         {
274                 report(out_hnd,"Stopped Service %s\n", svc_name);
275                 DEBUG(5,("cmd_svc_stop: succeeded\n"));
276         }
277         else
278                 report(out_hnd,"Failed Service Stopped (%s)\n", svc_name);
279         {
280                 DEBUG(5,("cmd_svc_stop: failed\n"));
281         }
282 }
283
284 /****************************************************************************
285 nt start service 
286 ****************************************************************************/
287 void cmd_svc_start(struct client_info *info, int argc, char *argv[])
288 {
289         BOOL res = True;
290         BOOL res1 = True;
291         char *svc_name;
292         BOOL res2 = True;
293         POLICY_HND pol_svc;
294         POLICY_HND pol_scm;
295         
296         fstring srv_name;
297
298         fstrcpy(srv_name, "\\\\");
299         fstrcat(srv_name, info->dest_host);
300         strupper(srv_name);
301
302         DEBUG(4,("cmd_svc_start: server:%s\n", srv_name));
303
304         if (argc < 2)
305         {
306                 report(out_hnd,"svcstart <service name> [arg 0] [arg 1]...]\n");
307                 return;
308         }
309
310         argv++;
311         argc--;
312
313         svc_name = argv[0];
314
315         argv++;
316         argc--;
317
318         /* open service control manager receive a policy handle */
319         res = res ? svc_open_sc_man( srv_name, NULL, 0x80000000,
320                                 &pol_scm) : False;
321
322         res1 = res ? svc_open_service( &pol_scm,
323                                        svc_name, 0x80000010,
324                                        &pol_svc) : False;
325         res2 = res1 ? svc_start_service( &pol_svc, argc, argv) : False;
326
327         res1 = res1 ? svc_close(&pol_svc) : False;
328         res  = res  ? svc_close(&pol_scm) : False;
329
330         if (res2)
331         {
332                 report(out_hnd,"Started Service %s\n", svc_name);
333                 DEBUG(5,("cmd_svc_start: succeeded\n"));
334         }
335         else
336                 report(out_hnd,"Failed Service Startup (%s)\n", svc_name);
337         {
338                 DEBUG(5,("cmd_svc_start: failed\n"));
339         }
340 }
341
342 /****************************************************************************
343 nt service set
344 ****************************************************************************/
345 void cmd_svc_set(struct client_info *info, int argc, char *argv[])
346 {
347         BOOL res = True;
348         BOOL res2 = True;
349         BOOL res3;
350         POLICY_HND pol_svc;
351         QUERY_SERVICE_CONFIG cfg;
352         uint32 svc_buf_size = 0x8000;
353
354         char *svc_name;
355
356         POLICY_HND pol_scm;
357         
358         fstring srv_name;
359
360         fstrcpy(srv_name, "\\\\");
361         fstrcat(srv_name, info->dest_host);
362         strupper(srv_name);
363
364         DEBUG(4,("cmd_svc_set: server:%s\n", srv_name));
365
366         if (argc < 2)
367         {
368                 report(out_hnd,"svcset <service name>\n");
369                 return;
370         }
371
372         svc_name = argv[1];
373
374         /* open service control manager receive a policy handle */
375         res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
376                                 &pol_scm) : False;
377
378         res2 = res ? svc_open_service( &pol_scm,
379                                        svc_name, 0x80000001,
380                                        &pol_svc) : False;
381         res3 = res2 ? svc_query_svc_cfg( &pol_svc, &cfg,
382                                        &svc_buf_size) : False;
383
384         if (res3)
385         {
386                 res3 = svc_change_svc_cfg(&pol_svc,
387                                    cfg.service_type,
388                                    cfg.start_type,
389                                    0xffffffff,
390                                    0,
391                                    NULL, NULL,
392                                    cfg.tag_id,
393                                    NULL, "administrator", NULL, NULL);
394                         
395         }
396
397         res2 = res2 ? svc_close(&pol_svc) : False;
398
399         res = res ? svc_close(&pol_scm) : False;
400
401         if (res3)
402         {
403                 DEBUG(5,("cmd_svc_set: change succeeded\n"));
404         }
405         else
406         {
407                 DEBUG(5,("cmd_svc_set: change failed\n"));
408         }
409 }
410