summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-03-24 18:05:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:56:18 -0500
commit9d009834a63e45e8a348419d4f5313757cff8c8d (patch)
treed0665f66b8d8273879564e0b64c8df7f7df23741
parenteb1adc527bb1b01f28fa86e7caa66c85181df764 (diff)
downloadsamba-9d009834a63e45e8a348419d4f5313757cff8c8d.tar.gz
samba-9d009834a63e45e8a348419d4f5313757cff8c8d.tar.bz2
samba-9d009834a63e45e8a348419d4f5313757cff8c8d.zip
r6040: finish out 'net rpc service list'
(This used to be commit 42588ba50cb1b47a00f3e0bed33ca3431eb8af14)
-rw-r--r--source3/include/rpc_client.h21
-rw-r--r--source3/include/rpc_svcctl.h2
-rw-r--r--source3/nsswitch/winbindd.h1
-rw-r--r--source3/rpc_client/cli_svcctl.c61
-rw-r--r--source3/utils/net_rpc_service.c27
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<out.returned; i++ ) {
+ svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
+ }
+
+ *service_array = services;
+ *returned = out.returned;
+
+
return out.status;
}
diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c
index 98711c95b6..3d6bf7617c 100644
--- a/source3/utils/net_rpc_service.c
+++ b/source3/utils/net_rpc_service.c
@@ -28,25 +28,46 @@ static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char
int argc, const char **argv )
{
POLICY_HND hSCM;
+ ENUM_SERVICES_STATUS *services;
WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+ fstring displayname;
+ uint32 num_services = 0;
+ int i;
if (argc != 0 ) {
d_printf("Usage: net rpc service list\n");
return NT_STATUS_OK;
}
- if ( !W_ERROR_IS_OK(result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE )) ) {
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
- d_printf("Successfully opened Service Control Manager.\n");
+ result = cli_svcctl_enumerate_services( cli, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
+ SVCCTL_STATE_ALL, &num_services, &services );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to enumerate services. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+ if ( num_services == 0 )
+ d_printf("No services returned\n");
+ for ( i=0; i<num_services; i++ ) {
+ rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
+ rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
+
+ d_printf("%s (%s)\n", displayname, servicename);
+ }
+
+done:
close_service_handle( cli, mem_ctx, &hSCM );
- return NT_STATUS_OK;
+ return werror_to_ntstatus(result);
}