More pstring elimination.
[Samba/vl.git] / source3 / rpc_client / cli_svcctl.c
blob95673c15654f53bbc491ac0e0b39f47890aa698e
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Gerald Carter 2005.
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.
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.
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/>.
21 #include "includes.h"
22 #include "rpc_client.h"
24 struct svc_state_msg {
25 uint32 flag;
26 const char *message;
29 static struct svc_state_msg state_msg_table[] = {
30 { SVCCTL_STOPPED, "stopped" },
31 { SVCCTL_START_PENDING, "start pending" },
32 { SVCCTL_STOP_PENDING, "stop pending" },
33 { SVCCTL_RUNNING, "running" },
34 { SVCCTL_CONTINUE_PENDING, "resume pending" },
35 { SVCCTL_PAUSE_PENDING, "pause pending" },
36 { SVCCTL_PAUSED, "paused" },
37 { 0, NULL }
41 /********************************************************************
42 ********************************************************************/
43 const char* svc_status_string( uint32 state )
45 fstring msg;
46 int i;
48 fstr_sprintf( msg, "Unknown State [%d]", state );
50 for ( i=0; state_msg_table[i].message; i++ ) {
51 if ( state_msg_table[i].flag == state ) {
52 fstrcpy( msg, state_msg_table[i].message );
53 break;
57 return talloc_strdup(talloc_tos(), msg);
60 /********************************************************************
61 ********************************************************************/
63 WERROR rpccli_svcctl_open_scm(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
64 POLICY_HND *hSCM, uint32 access_desired )
66 SVCCTL_Q_OPEN_SCMANAGER in;
67 SVCCTL_R_OPEN_SCMANAGER out;
68 prs_struct qbuf, rbuf;
69 fstring server;
71 ZERO_STRUCT(in);
72 ZERO_STRUCT(out);
74 /* leave the database name NULL to get the default service db */
76 in.database = NULL;
78 /* set the server name */
80 if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) )
81 return WERR_NOMEM;
82 fstr_sprintf( server, "\\\\%s", cli->cli->desthost );
83 init_unistr2( in.servername, server, UNI_STR_TERMINATE );
85 in.access = access_desired;
87 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W,
88 in, out,
89 qbuf, rbuf,
90 svcctl_io_q_open_scmanager,
91 svcctl_io_r_open_scmanager,
92 WERR_GENERAL_FAILURE );
94 if ( !W_ERROR_IS_OK( out.status ) )
95 return out.status;
97 memcpy( hSCM, &out.handle, sizeof(POLICY_HND) );
99 return out.status;
102 /********************************************************************
103 ********************************************************************/
105 WERROR rpccli_svcctl_open_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
106 POLICY_HND *hSCM, POLICY_HND *hService,
107 const char *servicename, uint32 access_desired )
109 SVCCTL_Q_OPEN_SERVICE in;
110 SVCCTL_R_OPEN_SERVICE out;
111 prs_struct qbuf, rbuf;
113 ZERO_STRUCT(in);
114 ZERO_STRUCT(out);
116 memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
117 init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE );
118 in.access = access_desired;
120 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W,
121 in, out,
122 qbuf, rbuf,
123 svcctl_io_q_open_service,
124 svcctl_io_r_open_service,
125 WERR_GENERAL_FAILURE );
127 if ( !W_ERROR_IS_OK( out.status ) )
128 return out.status;
130 memcpy( hService, &out.handle, sizeof(POLICY_HND) );
132 return out.status;
135 /*******************************************************************
136 *******************************************************************/
138 WERROR rpccli_svcctl_enumerate_services( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
139 POLICY_HND *hSCM, uint32 type, uint32 state,
140 uint32 *returned, ENUM_SERVICES_STATUS **service_array )
142 SVCCTL_Q_ENUM_SERVICES_STATUS in;
143 SVCCTL_R_ENUM_SERVICES_STATUS out;
144 prs_struct qbuf, rbuf;
145 uint32 resume = 0;
146 ENUM_SERVICES_STATUS *services;
147 int i;
149 ZERO_STRUCT(in);
150 ZERO_STRUCT(out);
152 /* setup the request */
154 memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
156 in.type = type;
157 in.state = state;
158 in.resume = &resume;
160 /* first time is to get the buffer size */
161 in.buffer_size = 0;
163 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
164 in, out,
165 qbuf, rbuf,
166 svcctl_io_q_enum_services_status,
167 svcctl_io_r_enum_services_status,
168 WERR_GENERAL_FAILURE );
170 /* second time with correct buffer size...should be ok */
172 if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
173 in.buffer_size = out.needed;
175 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
176 in, out,
177 qbuf, rbuf,
178 svcctl_io_q_enum_services_status,
179 svcctl_io_r_enum_services_status,
180 WERR_GENERAL_FAILURE );
183 if ( !W_ERROR_IS_OK(out.status) )
184 return out.status;
186 /* pull out the data */
187 if (out.returned) {
188 if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) )
189 return WERR_NOMEM;
190 } else {
191 services = NULL;
194 for ( i=0; i<out.returned; i++ ) {
195 svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
198 *service_array = services;
199 *returned = out.returned;
201 return out.status;
204 /*******************************************************************
205 *******************************************************************/
207 WERROR rpccli_svcctl_query_status( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
208 POLICY_HND *hService, SERVICE_STATUS *status )
210 SVCCTL_Q_QUERY_STATUS in;
211 SVCCTL_R_QUERY_STATUS out;
212 prs_struct qbuf, rbuf;
214 ZERO_STRUCT(in);
215 ZERO_STRUCT(out);
217 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
219 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS,
220 in, out,
221 qbuf, rbuf,
222 svcctl_io_q_query_status,
223 svcctl_io_r_query_status,
224 WERR_GENERAL_FAILURE );
226 if ( !W_ERROR_IS_OK( out.status ) )
227 return out.status;
229 memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
231 return out.status;
234 /*******************************************************************
235 *******************************************************************/
237 WERROR rpccli_svcctl_query_config(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
238 POLICY_HND *hService, SERVICE_CONFIG *config )
240 SVCCTL_Q_QUERY_SERVICE_CONFIG in;
241 SVCCTL_R_QUERY_SERVICE_CONFIG out;
242 prs_struct qbuf, rbuf;
244 ZERO_STRUCT(in);
245 ZERO_STRUCT(out);
247 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
248 in.buffer_size = 0;
251 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
252 in, out,
253 qbuf, rbuf,
254 svcctl_io_q_query_service_config,
255 svcctl_io_r_query_service_config,
256 WERR_GENERAL_FAILURE );
258 if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
259 in.buffer_size = out.needed;
261 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
262 in, out,
263 qbuf, rbuf,
264 svcctl_io_q_query_service_config,
265 svcctl_io_r_query_service_config,
266 WERR_GENERAL_FAILURE );
269 if ( !W_ERROR_IS_OK( out.status ) )
270 return out.status;
272 memcpy( config, &out.config, sizeof(SERVICE_CONFIG) );
274 config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
275 config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
276 config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
277 config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
278 config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
280 if ( out.config.executablepath ) {
281 config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
282 copy_unistr2( config->executablepath, out.config.executablepath );
285 if ( out.config.loadordergroup ) {
286 config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
287 copy_unistr2( config->loadordergroup, out.config.loadordergroup );
290 if ( out.config.dependencies ) {
291 config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
292 copy_unistr2( config->dependencies, out.config.dependencies );
295 if ( out.config.startname ) {
296 config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
297 copy_unistr2( config->startname, out.config.startname );
300 if ( out.config.displayname ) {
301 config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
302 copy_unistr2( config->displayname, out.config.displayname );
305 return out.status;
308 /*******************************************************************
309 *******************************************************************/
311 WERROR rpccli_svcctl_start_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
312 POLICY_HND *hService,
313 const char **parm_array, uint32 parmcount )
315 SVCCTL_Q_START_SERVICE in;
316 SVCCTL_R_START_SERVICE out;
317 prs_struct qbuf, rbuf;
319 ZERO_STRUCT(in);
320 ZERO_STRUCT(out);
322 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
324 in.parmcount = 0;
325 in.parameters = NULL;
327 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
328 in, out,
329 qbuf, rbuf,
330 svcctl_io_q_start_service,
331 svcctl_io_r_start_service,
332 WERR_GENERAL_FAILURE );
334 return out.status;
337 /*******************************************************************
338 *******************************************************************/
340 WERROR rpccli_svcctl_control_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
341 POLICY_HND *hService, uint32 control,
342 SERVICE_STATUS *status )
344 SVCCTL_Q_CONTROL_SERVICE in;
345 SVCCTL_R_CONTROL_SERVICE out;
346 prs_struct qbuf, rbuf;
348 ZERO_STRUCT(in);
349 ZERO_STRUCT(out);
351 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
352 in.control = control;
354 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
355 in, out,
356 qbuf, rbuf,
357 svcctl_io_q_control_service,
358 svcctl_io_r_control_service,
359 WERR_GENERAL_FAILURE );
361 if ( !W_ERROR_IS_OK( out.status ) )
362 return out.status;
364 memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
366 return out.status;
370 /*******************************************************************
371 *******************************************************************/
373 WERROR rpccli_svcctl_get_dispname( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
374 POLICY_HND *hService, fstring displayname )
376 SVCCTL_Q_GET_DISPLAY_NAME in;
377 SVCCTL_R_GET_DISPLAY_NAME out;
378 prs_struct qbuf, rbuf;
380 ZERO_STRUCT(in);
381 ZERO_STRUCT(out);
383 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
384 in.display_name_len = 0;
386 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
387 in, out,
388 qbuf, rbuf,
389 svcctl_io_q_get_display_name,
390 svcctl_io_r_get_display_name,
391 WERR_GENERAL_FAILURE );
393 /* second time with correct buffer size...should be ok */
395 if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
396 in.display_name_len = out.display_name_len;
398 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
399 in, out,
400 qbuf, rbuf,
401 svcctl_io_q_get_display_name,
402 svcctl_io_r_get_display_name,
403 WERR_GENERAL_FAILURE );
406 if ( !W_ERROR_IS_OK( out.status ) )
407 return out.status;
409 rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
411 return out.status;