From 9d009834a63e45e8a348419d4f5313757cff8c8d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Mar 2005 18:05:31 +0000 Subject: r6040: finish out 'net rpc service list' (This used to be commit 42588ba50cb1b47a00f3e0bed33ca3431eb8af14) --- source3/include/rpc_client.h | 21 +++++++++++--- source3/include/rpc_svcctl.h | 2 +- source3/nsswitch/winbindd.h | 1 - source3/rpc_client/cli_svcctl.c | 61 ++++++++++++++++++++++++++++------------- source3/utils/net_rpc_service.c | 27 ++++++++++++++++-- 5 files changed, 84 insertions(+), 28 deletions(-) diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h index bce9ec7f27..4ac2f43ee0 100644 --- a/source3/include/rpc_client.h +++ b/source3/include/rpc_client.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB parameters and setup - Copyright (C) Elrond 2000 + Copyright (C) Gerald (Jerry) Carter 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,8 +21,21 @@ #ifndef _RPC_CLIENT_H #define _RPC_CLIENT_H -#if 0 /* JERRY */ -#include "rpc_client_proto.h" -#endif +/* macro to expand cookie-cutter code in cli_xxx() */ + +#define CLI_DO_RPC( pcli, ctx, pipe_num, opnum, q_in, r_out, q_ps, r_ps, q_io_fn, r_io_fn, default_error) \ +{ r_out.status = default_error;\ + prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \ + prs_init( &r_ps, 0, ctx, UNMARSHALL );\ + if ( q_io_fn("", &q_in, &q_ps, 0) ) {\ + if ( rpc_api_pipe_req(pcli, pipe_num, opnum, &q_ps, &r_ps) ) {\ + if (!r_io_fn("", &r_out, &r_ps, 0)) {\ + r_out.status = default_error;\ + }\ + }\ + }\ + prs_mem_free( &q_ps );\ + prs_mem_free( &r_ps );\ +} #endif /* _RPC_CLIENT_H */ diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index 55b7828d35..069d544b1f 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -50,7 +50,7 @@ /* SERVER_STATUS - state */ #define SVCCTL_STATE_ACTIVE 0x00000001 #define SVCCTL_STATE_INACTIVE 0x00000002 -#define SVCCTL_STATE_ALL ( SVC_STATE_ACTIVE | SVC_STATE_INACTIVE ) +#define SVCCTL_STATE_ALL ( SVCCTL_STATE_ACTIVE | SVCCTL_STATE_INACTIVE ) /* SERVER_STATUS - CurrentState */ diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index cd1d16e344..863ae35fed 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -245,7 +245,6 @@ struct winbindd_idmap_methods { #include "nsswitch/winbindd_proto.h" #include "rpc_parse.h" -#include "rpc_client.h" #define WINBINDD_ESTABLISH_LOOP 30 #define WINBINDD_RESCAN_FREQ 300 diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index 1702112bba..74d6483b17 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -20,24 +20,7 @@ #include "includes.h" - -/* macro to expand cookie-cutter code */ - -#define CLI_DO_RPC( cli, mem_ctx, pipe_num, opnum, in, out, qbuf, rbuf, q_io_fn, r_io_fn, default_error) \ -{ out.status = default_error;\ - prs_init( &qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL ); \ - prs_init( &rbuf, 0, mem_ctx, UNMARSHALL );\ - if ( q_io_fn("", &in, &qbuf, 0) ) {\ - if ( rpc_api_pipe_req(cli, pipe_num, opnum, &qbuf, &rbuf) ) {\ - if (!r_io_fn("", &out, &rbuf, 0)) {\ - out.status = default_error;\ - }\ - }\ - }\ - prs_mem_free( &qbuf );\ - prs_mem_free( &rbuf );\ -} - +#include "rpc_client.h" /******************************************************************** ********************************************************************/ @@ -110,14 +93,28 @@ WERROR close_service_handle( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, uint32 type, uint32 state, - uint32 *resume, uint32 returned ) + uint32 *returned, ENUM_SERVICES_STATUS **service_array ) { SVCCTL_Q_ENUM_SERVICES_STATUS in; SVCCTL_R_ENUM_SERVICES_STATUS out; prs_struct qbuf, rbuf; + uint32 resume = 0; + ENUM_SERVICES_STATUS *services; + int i; ZERO_STRUCT(in); ZERO_STRUCT(out); + + /* setup the request */ + + memcpy( &in.handle, hSCM, sizeof(POLICY_HND) ); + + in.type = type; + in.state = state; + in.resume = &resume; + + /* first time is to get the buffer size */ + in.buffer_size = 0; CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, in, out, @@ -126,8 +123,34 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx svcctl_io_r_enum_services_status, WERR_GENERAL_FAILURE ); + /* second time with correct buffer size...should be ok */ + + if ( !W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { + in.buffer_size = out.needed; + + CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, + in, out, + qbuf, rbuf, + svcctl_io_q_enum_services_status, + svcctl_io_r_enum_services_status, + WERR_GENERAL_FAILURE ); + } + if ( !W_ERROR_IS_OK(out.status) ) return out.status; + + /* pull out the data */ + if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) ) + return WERR_NOMEM; + + for ( i=0; i