r6040: finish out 'net rpc service list'
authorGerald Carter <jerry@samba.org>
Thu, 24 Mar 2005 18:05:31 +0000 (18:05 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:56:18 +0000 (10:56 -0500)
source/include/rpc_client.h
source/include/rpc_svcctl.h
source/nsswitch/winbindd.h
source/rpc_client/cli_svcctl.c
source/utils/net_rpc_service.c

index bce9ec7f2739508c259bdcdc2399feb4eda147f2..4ac2f43ee00a5424db87d7cd4765d2b19a9fbc69 100644 (file)
@@ -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
 #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 */
index 55b7828d35c2cd0448aecca1469897677974b23f..069d544b1feb8b9f4a12a28454e04c131bbf2dd2 100644 (file)
@@ -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 */
 
index cd1d16e34411349ac7aa6a26518fb0b38ea575ac..863ae35fed4a999102ed0e25f03ba75a5e65fe98 100644 (file)
@@ -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
index 1702112bba3963ce86dc6f05e9d5174b04e11491..74d6483b177c0b80b1a031d9cd9e5076f1cd5bdc 100644 (file)
 
 
 #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;
 }
index 98711c95b6ba7300785ede13fc2534dac501e376..3d6bf7617cfdb3b4f04e8acb352e34c485b923af 100644 (file)
@@ -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);
 }