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/>.
22 #include "rpc_client.h"
24 struct svc_state_msg
{
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" },
41 /********************************************************************
42 ********************************************************************/
43 const char* svc_status_string( uint32 state
)
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
);
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
;
74 /* leave the database name NULL to get the default service db */
78 /* set the server name */
80 if ( !(in
.servername
= TALLOC_P( mem_ctx
, UNISTR2
)) )
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
,
90 svcctl_io_q_open_scmanager
,
91 svcctl_io_r_open_scmanager
,
92 WERR_GENERAL_FAILURE
);
94 if ( !W_ERROR_IS_OK( out
.status
) )
97 memcpy( hSCM
, &out
.handle
, sizeof(POLICY_HND
) );
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
;
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
,
123 svcctl_io_q_open_service
,
124 svcctl_io_r_open_service
,
125 WERR_GENERAL_FAILURE
);
127 if ( !W_ERROR_IS_OK( out
.status
) )
130 memcpy( hService
, &out
.handle
, sizeof(POLICY_HND
) );
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
;
146 ENUM_SERVICES_STATUS
*services
;
152 /* setup the request */
154 memcpy( &in
.handle
, hSCM
, sizeof(POLICY_HND
) );
160 /* first time is to get the buffer size */
163 CLI_DO_RPC_WERR( cli
, mem_ctx
, PI_SVCCTL
, SVCCTL_ENUM_SERVICES_STATUS_W
,
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
,
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
) )
186 /* pull out the data */
188 if ( !(services
= TALLOC_ARRAY( mem_ctx
, ENUM_SERVICES_STATUS
, out
.returned
)) )
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
;
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
;
217 memcpy( &in
.handle
, hService
, sizeof(POLICY_HND
) );
219 CLI_DO_RPC_WERR( cli
, mem_ctx
, PI_SVCCTL
, SVCCTL_QUERY_STATUS
,
222 svcctl_io_q_query_status
,
223 svcctl_io_r_query_status
,
224 WERR_GENERAL_FAILURE
);
226 if ( !W_ERROR_IS_OK( out
.status
) )
229 memcpy( status
, &out
.svc_status
, sizeof(SERVICE_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
;
247 memcpy( &in
.handle
, hService
, sizeof(POLICY_HND
) );
251 CLI_DO_RPC_WERR( cli
, mem_ctx
, PI_SVCCTL
, SVCCTL_QUERY_SERVICE_CONFIG_W
,
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
,
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
) )
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
);
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
;
322 memcpy( &in
.handle
, hService
, sizeof(POLICY_HND
) );
325 in
.parameters
= NULL
;
327 CLI_DO_RPC_WERR( cli
, mem_ctx
, PI_SVCCTL
, SVCCTL_START_SERVICE_W
,
330 svcctl_io_q_start_service
,
331 svcctl_io_r_start_service
,
332 WERR_GENERAL_FAILURE
);
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
;
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
,
357 svcctl_io_q_control_service
,
358 svcctl_io_r_control_service
,
359 WERR_GENERAL_FAILURE
);
361 if ( !W_ERROR_IS_OK( out
.status
) )
364 memcpy( status
, &out
.svc_status
, sizeof(SERVICE_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
;
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
,
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
,
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
) )
409 rpcstr_pull( displayname
, out
.displayname
.buffer
, sizeof(displayname
), -1, STR_TERMINATE
);