#include "includes.h"
#include "torture/torture.h"
#include "librpc/gen_ndr/ndr_svcctl_c.h"
+#include "librpc/gen_ndr/ndr_svcctl.h"
#include "torture/rpc/rpc.h"
+#include "param/param.h"
static bool test_OpenSCManager(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
{
struct policy_handle h, s;
NTSTATUS status;
- uint32_t info_level = 0;
+ uint32_t info_level = SVC_STATUS_PROCESS_INFO;
uint8_t *buffer;
- uint32_t buf_size = 0;
- uint32_t bytes_needed = 0;
+ uint32_t offered = 0;
+ uint32_t needed = 0;
if (!test_OpenSCManager(p, tctx, &h))
return false;
r.in.handle = &s;
r.in.info_level = info_level;
- r.in.buf_size = buf_size;
+ r.in.offered = offered;
r.out.buffer = buffer;
- r.out.bytes_needed = &bytes_needed;
+ r.out.needed = &needed;
status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- r.in.buf_size = bytes_needed;
- buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.in.offered = needed;
+ buffer = talloc_array(tctx, uint8_t, needed);
r.out.buffer = buffer;
status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
uint32_t info_level = SERVICE_CONFIG_DESCRIPTION;
uint8_t *buffer;
- uint32_t buf_size = 0;
- uint32_t bytes_needed = 0;
+ uint32_t offered = 0;
+ uint32_t needed = 0;
if (!test_OpenSCManager(p, tctx, &h))
return false;
r.in.handle = &s;
r.in.info_level = info_level;
- r.in.buf_size = buf_size;
+ r.in.offered = offered;
r.out.buffer = buffer;
- r.out.bytes_needed = &bytes_needed;
+ r.out.needed = &needed;
status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
- r.in.buf_size = bytes_needed;
- buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.in.offered = needed;
+ buffer = talloc_array(tctx, uint8_t, needed);
+ r.out.buffer = buffer;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
+ }
+
+ r.in.info_level = SERVICE_CONFIG_FAILURE_ACTIONS;
+ r.in.offered = offered;
+ r.out.buffer = buffer;
+ r.out.needed = &needed;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.offered = needed;
+ buffer = talloc_array(tctx, uint8_t, needed);
r.out.buffer = buffer;
status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
int i;
NTSTATUS status;
uint32_t resume_handle = 0;
- struct ENUM_SERVICE_STATUS *service = NULL;
- uint32_t bytes_needed = 0;
+ struct ENUM_SERVICE_STATUSW *service = NULL;
+ uint32_t needed = 0;
uint32_t services_returned = 0;
if (!test_OpenSCManager(p, tctx, &h))
r.in.handle = &h;
r.in.type = SERVICE_TYPE_WIN32;
r.in.state = SERVICE_STATE_ALL;
- r.in.buf_size = 0;
+ r.in.offered = 0;
r.in.resume_handle = &resume_handle;
r.out.service = NULL;
r.out.resume_handle = &resume_handle;
r.out.services_returned = &services_returned;
- r.out.bytes_needed = &bytes_needed;
+ r.out.needed = &needed;
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
- r.in.buf_size = bytes_needed;
- r.out.service = talloc_array(tctx, uint8_t, bytes_needed);
+ r.in.offered = needed;
+ r.out.service = talloc_array(tctx, uint8_t, needed);
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
torture_assert_werr_ok(tctx, r.out.result, "EnumServicesStatus failed");
+ }
+
+ if (services_returned > 0) {
- service = (struct ENUM_SERVICE_STATUS *)r.out.service;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ struct ndr_pull *ndr;
+
+ blob.length = r.in.offered;
+ blob.data = talloc_steal(tctx, r.out.service);
+
+ ndr = ndr_pull_init_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx));
+
+ service = talloc_array(tctx, struct ENUM_SERVICE_STATUSW, services_returned);
+ if (!service) {
+ return false;
+ }
+
+ ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array(
+ ndr, services_returned, service);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return false;
+ }
}
for(i = 0; i < services_returned; i++) {
- printf("Type: %d, State: %d\n", service[i].status.type, service[i].status.state);
+
+ printf("%-20s \"%s\", Type: %d, State: %d\n",
+ service[i].service_name, service[i].display_name,
+ service[i].status.type, service[i].status.state);
}
if (!test_CloseServiceHandle(p, tctx, &h))