00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023 #include "rpc_client.h"
00024
00025 struct svc_state_msg {
00026 uint32 flag;
00027 const char *message;
00028 };
00029
00030 static struct svc_state_msg state_msg_table[] = {
00031 { SVCCTL_STOPPED, "stopped" },
00032 { SVCCTL_START_PENDING, "start pending" },
00033 { SVCCTL_STOP_PENDING, "stop pending" },
00034 { SVCCTL_RUNNING, "running" },
00035 { SVCCTL_CONTINUE_PENDING, "resume pending" },
00036 { SVCCTL_PAUSE_PENDING, "pause pending" },
00037 { SVCCTL_PAUSED, "paused" },
00038 { 0, NULL }
00039 };
00040
00041
00042
00043
00044 const char* svc_status_string( uint32 state )
00045 {
00046 static fstring msg;
00047 int i;
00048
00049 fstr_sprintf( msg, "Unknown State [%d]", state );
00050
00051 for ( i=0; state_msg_table[i].message; i++ ) {
00052 if ( state_msg_table[i].flag == state ) {
00053 fstrcpy( msg, state_msg_table[i].message );
00054 break;
00055 }
00056 }
00057
00058 return msg;
00059 }
00060
00061
00062
00063
00064 WERROR rpccli_svcctl_open_scm(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00065 POLICY_HND *hSCM, uint32 access_desired )
00066 {
00067 SVCCTL_Q_OPEN_SCMANAGER in;
00068 SVCCTL_R_OPEN_SCMANAGER out;
00069 prs_struct qbuf, rbuf;
00070 fstring server;
00071
00072 ZERO_STRUCT(in);
00073 ZERO_STRUCT(out);
00074
00075
00076
00077 in.database = NULL;
00078
00079
00080
00081 if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) )
00082 return WERR_NOMEM;
00083 fstr_sprintf( server, "\\\\%s", cli->cli->desthost );
00084 init_unistr2( in.servername, server, UNI_STR_TERMINATE );
00085
00086 in.access = access_desired;
00087
00088 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W,
00089 in, out,
00090 qbuf, rbuf,
00091 svcctl_io_q_open_scmanager,
00092 svcctl_io_r_open_scmanager,
00093 WERR_GENERAL_FAILURE );
00094
00095 if ( !W_ERROR_IS_OK( out.status ) )
00096 return out.status;
00097
00098 memcpy( hSCM, &out.handle, sizeof(POLICY_HND) );
00099
00100 return out.status;
00101 }
00102
00103
00104
00105
00106 WERROR rpccli_svcctl_open_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00107 POLICY_HND *hSCM, POLICY_HND *hService,
00108 const char *servicename, uint32 access_desired )
00109 {
00110 SVCCTL_Q_OPEN_SERVICE in;
00111 SVCCTL_R_OPEN_SERVICE out;
00112 prs_struct qbuf, rbuf;
00113
00114 ZERO_STRUCT(in);
00115 ZERO_STRUCT(out);
00116
00117 memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
00118 init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE );
00119 in.access = access_desired;
00120
00121 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W,
00122 in, out,
00123 qbuf, rbuf,
00124 svcctl_io_q_open_service,
00125 svcctl_io_r_open_service,
00126 WERR_GENERAL_FAILURE );
00127
00128 if ( !W_ERROR_IS_OK( out.status ) )
00129 return out.status;
00130
00131 memcpy( hService, &out.handle, sizeof(POLICY_HND) );
00132
00133 return out.status;
00134 }
00135
00136
00137
00138
00139 WERROR rpccli_svcctl_close_service(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
00140 {
00141 SVCCTL_Q_CLOSE_SERVICE in;
00142 SVCCTL_R_CLOSE_SERVICE out;
00143 prs_struct qbuf, rbuf;
00144
00145 ZERO_STRUCT(in);
00146 ZERO_STRUCT(out);
00147
00148 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00149
00150 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CLOSE_SERVICE,
00151 in, out,
00152 qbuf, rbuf,
00153 svcctl_io_q_close_service,
00154 svcctl_io_r_close_service,
00155 WERR_GENERAL_FAILURE );
00156
00157 return out.status;
00158 }
00159
00160
00161
00162
00163 WERROR rpccli_svcctl_enumerate_services( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00164 POLICY_HND *hSCM, uint32 type, uint32 state,
00165 uint32 *returned, ENUM_SERVICES_STATUS **service_array )
00166 {
00167 SVCCTL_Q_ENUM_SERVICES_STATUS in;
00168 SVCCTL_R_ENUM_SERVICES_STATUS out;
00169 prs_struct qbuf, rbuf;
00170 uint32 resume = 0;
00171 ENUM_SERVICES_STATUS *services;
00172 int i;
00173
00174 ZERO_STRUCT(in);
00175 ZERO_STRUCT(out);
00176
00177
00178
00179 memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
00180
00181 in.type = type;
00182 in.state = state;
00183 in.resume = &resume;
00184
00185
00186 in.buffer_size = 0;
00187
00188 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
00189 in, out,
00190 qbuf, rbuf,
00191 svcctl_io_q_enum_services_status,
00192 svcctl_io_r_enum_services_status,
00193 WERR_GENERAL_FAILURE );
00194
00195
00196
00197 if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
00198 in.buffer_size = out.needed;
00199
00200 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
00201 in, out,
00202 qbuf, rbuf,
00203 svcctl_io_q_enum_services_status,
00204 svcctl_io_r_enum_services_status,
00205 WERR_GENERAL_FAILURE );
00206 }
00207
00208 if ( !W_ERROR_IS_OK(out.status) )
00209 return out.status;
00210
00211
00212 if (out.returned) {
00213 if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) )
00214 return WERR_NOMEM;
00215 } else {
00216 services = NULL;
00217 }
00218
00219 for ( i=0; i<out.returned; i++ ) {
00220 svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
00221 }
00222
00223 *service_array = services;
00224 *returned = out.returned;
00225
00226 return out.status;
00227 }
00228
00229
00230
00231
00232 WERROR rpccli_svcctl_query_status( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00233 POLICY_HND *hService, SERVICE_STATUS *status )
00234 {
00235 SVCCTL_Q_QUERY_STATUS in;
00236 SVCCTL_R_QUERY_STATUS out;
00237 prs_struct qbuf, rbuf;
00238
00239 ZERO_STRUCT(in);
00240 ZERO_STRUCT(out);
00241
00242 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00243
00244 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS,
00245 in, out,
00246 qbuf, rbuf,
00247 svcctl_io_q_query_status,
00248 svcctl_io_r_query_status,
00249 WERR_GENERAL_FAILURE );
00250
00251 if ( !W_ERROR_IS_OK( out.status ) )
00252 return out.status;
00253
00254 memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
00255
00256 return out.status;
00257 }
00258
00259
00260
00261
00262 WERROR rpccli_svcctl_query_config(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00263 POLICY_HND *hService, SERVICE_CONFIG *config )
00264 {
00265 SVCCTL_Q_QUERY_SERVICE_CONFIG in;
00266 SVCCTL_R_QUERY_SERVICE_CONFIG out;
00267 prs_struct qbuf, rbuf;
00268
00269 ZERO_STRUCT(in);
00270 ZERO_STRUCT(out);
00271
00272 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00273 in.buffer_size = 0;
00274
00275
00276 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
00277 in, out,
00278 qbuf, rbuf,
00279 svcctl_io_q_query_service_config,
00280 svcctl_io_r_query_service_config,
00281 WERR_GENERAL_FAILURE );
00282
00283 if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
00284 in.buffer_size = out.needed;
00285
00286 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
00287 in, out,
00288 qbuf, rbuf,
00289 svcctl_io_q_query_service_config,
00290 svcctl_io_r_query_service_config,
00291 WERR_GENERAL_FAILURE );
00292 }
00293
00294 if ( !W_ERROR_IS_OK( out.status ) )
00295 return out.status;
00296
00297 memcpy( config, &out.config, sizeof(SERVICE_CONFIG) );
00298
00299 config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00300 config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00301 config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00302 config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00303 config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00304
00305 if ( out.config.executablepath ) {
00306 config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00307 copy_unistr2( config->executablepath, out.config.executablepath );
00308 }
00309
00310 if ( out.config.loadordergroup ) {
00311 config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00312 copy_unistr2( config->loadordergroup, out.config.loadordergroup );
00313 }
00314
00315 if ( out.config.dependencies ) {
00316 config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00317 copy_unistr2( config->dependencies, out.config.dependencies );
00318 }
00319
00320 if ( out.config.startname ) {
00321 config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00322 copy_unistr2( config->startname, out.config.startname );
00323 }
00324
00325 if ( out.config.displayname ) {
00326 config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
00327 copy_unistr2( config->displayname, out.config.displayname );
00328 }
00329
00330 return out.status;
00331 }
00332
00333
00334
00335
00336 WERROR rpccli_svcctl_start_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00337 POLICY_HND *hService,
00338 const char **parm_array, uint32 parmcount )
00339 {
00340 SVCCTL_Q_START_SERVICE in;
00341 SVCCTL_R_START_SERVICE out;
00342 prs_struct qbuf, rbuf;
00343
00344 ZERO_STRUCT(in);
00345 ZERO_STRUCT(out);
00346
00347 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00348
00349 in.parmcount = 0;
00350 in.parameters = NULL;
00351
00352 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
00353 in, out,
00354 qbuf, rbuf,
00355 svcctl_io_q_start_service,
00356 svcctl_io_r_start_service,
00357 WERR_GENERAL_FAILURE );
00358
00359 return out.status;
00360 }
00361
00362
00363
00364
00365 WERROR rpccli_svcctl_control_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00366 POLICY_HND *hService, uint32 control,
00367 SERVICE_STATUS *status )
00368 {
00369 SVCCTL_Q_CONTROL_SERVICE in;
00370 SVCCTL_R_CONTROL_SERVICE out;
00371 prs_struct qbuf, rbuf;
00372
00373 ZERO_STRUCT(in);
00374 ZERO_STRUCT(out);
00375
00376 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00377 in.control = control;
00378
00379 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
00380 in, out,
00381 qbuf, rbuf,
00382 svcctl_io_q_control_service,
00383 svcctl_io_r_control_service,
00384 WERR_GENERAL_FAILURE );
00385
00386 if ( !W_ERROR_IS_OK( out.status ) )
00387 return out.status;
00388
00389 memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
00390
00391 return out.status;
00392 }
00393
00394
00395
00396
00397
00398 WERROR rpccli_svcctl_get_dispname( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00399 POLICY_HND *hService, fstring displayname )
00400 {
00401 SVCCTL_Q_GET_DISPLAY_NAME in;
00402 SVCCTL_R_GET_DISPLAY_NAME out;
00403 prs_struct qbuf, rbuf;
00404
00405 ZERO_STRUCT(in);
00406 ZERO_STRUCT(out);
00407
00408 memcpy( &in.handle, hService, sizeof(POLICY_HND) );
00409 in.display_name_len = 0;
00410
00411 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
00412 in, out,
00413 qbuf, rbuf,
00414 svcctl_io_q_get_display_name,
00415 svcctl_io_r_get_display_name,
00416 WERR_GENERAL_FAILURE );
00417
00418
00419
00420 if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
00421 in.display_name_len = out.display_name_len;
00422
00423 CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
00424 in, out,
00425 qbuf, rbuf,
00426 svcctl_io_q_get_display_name,
00427 svcctl_io_r_get_display_name,
00428 WERR_GENERAL_FAILURE );
00429 }
00430
00431 if ( !W_ERROR_IS_OK( out.status ) )
00432 return out.status;
00433
00434 rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
00435
00436 return out.status;
00437 }