diff options
-rw-r--r-- | source3/utils/net_rpc_service.c | 87 |
1 files changed, 68 insertions, 19 deletions
diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index 51d7bfbb23..236414222c 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -200,14 +200,17 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c, const char **argv ) { POLICY_HND hSCM; - ENUM_SERVICES_STATUS *services; + struct ENUM_SERVICE_STATUSW *services = NULL; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; - fstring servicename; - fstring displayname; - uint32 num_services = 0; int i; + uint8_t *buffer = NULL; + uint32_t buf_size = 0; + uint32_t bytes_needed = 0; + uint32_t num_services = 0; + uint32_t resume_handle = 0; + if (argc != 0 ) { d_printf("Usage: net rpc service list\n"); return NT_STATUS_OK; @@ -224,28 +227,74 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c, return werror_to_ntstatus(result); } - result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SERVICE_TYPE_WIN32, - SERVICE_STATE_ALL, &num_services, &services ); + do { + status = rpccli_svcctl_EnumServicesStatusW(pipe_hnd, mem_ctx, + &hSCM, + SERVICE_TYPE_WIN32, + SERVICE_STATE_ALL, + buffer, + buf_size, + &bytes_needed, + &num_services, + &resume_handle, + &result); - if ( !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to enumerate services. [%s]\n", win_errstr(result)); - goto done; - } + if (NT_STATUS_IS_ERR(status)) { + d_fprintf(stderr, "Failed to enumerate services. [%s]\n", + win_errstr(result)); + break; + } - if ( num_services == 0 ) - d_printf("No services returned\n"); + if (W_ERROR_EQUAL(result, WERR_MORE_DATA) && bytes_needed > 0) { + buffer = talloc_array(mem_ctx, uint8_t, bytes_needed); + buf_size = bytes_needed; + continue; + } - 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 ); + if ( num_services == 0 ) { + d_printf("No services returned\n"); + break; + } - d_printf("%-20s \"%s\"\n", servicename, displayname); - } + { + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct ndr_pull *ndr; + + blob.length = buf_size; + blob.data = talloc_steal(mem_ctx, buffer); + + services = talloc_array(mem_ctx, struct ENUM_SERVICE_STATUSW, num_services); + if (!services) { + status = NT_STATUS_NO_MEMORY; + break; + } + + ndr = ndr_pull_init_blob(&blob, mem_ctx, NULL); + if (ndr == NULL) { + status = NT_STATUS_NO_MEMORY; + break; + } + + ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array( + ndr, num_services, services); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + break; + } + + for ( i=0; i<num_services; i++ ) { + d_printf("%-20s \"%s\"\n", + services[i].service_name, + services[i].display_name); + } + } + + } while (W_ERROR_EQUAL(result, WERR_MORE_DATA)); -done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - return werror_to_ntstatus(result); + return status; } /******************************************************************** |