#include "includes.h"
#include "libcli/raw/libcliraw.h"
+#include "libcli/rap/rap.h"
#include "torture/torture.h"
#include "torture/util.h"
+#include "torture/rap/proto.h"
#include "librpc/gen_ndr/ndr_lsa.h"
#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "librpc/gen_ndr/ndr_samr.h"
#include "librpc/gen_ndr/ndr_srvsvc_c.h"
#include "librpc/gen_ndr/ndr_spoolss.h"
#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "librpc/gen_ndr/ndr_winreg.h"
+#include "librpc/gen_ndr/ndr_winreg_c.h"
+#include "librpc/gen_ndr/ndr_wkssvc.h"
+#include "librpc/gen_ndr/ndr_wkssvc_c.h"
#include "lib/cmdline/popt_common.h"
#include "librpc/rpc/dcerpc.h"
#include "torture/rpc/rpc.h"
#include "libcli/composite/composite.h"
#include "libcli/smb_composite/smb_composite.h"
#include "libcli/auth/libcli_auth.h"
-#include "libcli/auth/credentials.h"
#include "lib/crypto/crypto.h"
#include "libcli/security/proto.h"
}
status = smbcli_full_connection(mem_ctx, &cli,
- lp_parm_string(-1, "torture", "host"),
+ torture_setting_string(torture, "host", NULL),
"IPC$", NULL, cmdline_credentials,
NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- status = dcerpc_pipe_open_smb(lsa_pipe->conn, cli->tree, "\\lsarpc");
+ status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
nt_errstr(status));
goto done;
}
+ session2->vuid = setup.out.vuid;
tmp = cli->tree->session;
cli->tree->session = session2;
goto done;
}
- status = dcerpc_pipe_open_smb(lsa_pipe->conn, cli->tree, "\\lsarpc");
+ status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
}
status = smbcli_full_connection(mem_ctx, &cli,
- lp_parm_string(-1, "torture", "host"),
+ torture_setting_string(torture, "host", NULL),
"IPC$", NULL, cmdline_credentials,
NULL);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
- status = dcerpc_pipe_open_smb(samr_pipe->conn, cli->tree, "\\samr");
+ status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
qui.out.info->info21.force_password_change = 0;
qui.out.info->info21.account_name.string = NULL;
qui.out.info->info21.rid = 0;
+ qui.out.info->info21.acct_expiry = 0;
qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
u_info.info21 = qui.out.info->info21;
goto done;
}
- status = dcerpc_pipe_open_smb(net_pipe->conn, cli->tree, "\\netlogon");
+ status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
goto done;
}
- status = dcerpc_pipe_open_smb(net_pipe->conn, cli->tree, "\\netlogon");
+ status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
const char *wks_name;
int i;
- wks_name = lp_parm_string(-1, "torture", "wksname");
+ wks_name = torture_setting_string(torture, "wksname", NULL);
if (wks_name == NULL) {
wks_name = get_myname();
}
- mem_ctx = talloc_init("torture_bind_authcontext");
+ mem_ctx = talloc_init("torture_netlogon_samba3");
if (mem_ctx == NULL) {
d_printf("talloc_init failed\n");
}
status = smbcli_full_connection(mem_ctx, &cli,
- lp_parm_string(-1, "torture", "host"),
+ torture_setting_string(torture, "host", NULL),
"IPC$", NULL, anon_creds, NULL);
if (!NT_STATUS_IS_OK(status)) {
d_printf("smbcli_full_connection failed: %s\n",
struct cli_credentials *anon_creds;
const char *wks_name;
- wks_name = lp_parm_string(-1, "torture", "wksname");
- if (wks_name == NULL) {
- wks_name = get_myname();
- }
+ wks_name = torture_setting_string(torture, "wksname", get_myname());
mem_ctx = talloc_init("torture_samba3_sessionkey");
ret = True;
- if (!lp_parm_bool(-1, "target", "samba3", False)) {
+ if (!torture_setting_bool(torture, "samba3", False)) {
/* Samba3 in the build farm right now does this happily. Need
* to fix :-) */
return NT_STATUS_NO_MEMORY;
}
- status = dcerpc_pipe_open_smb(result->conn, tree, pipe_name);
+ status = dcerpc_pipe_open_smb(result, tree, pipe_name);
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_pipe_open_smb failed: %s\n",
nt_errstr(status));
status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ printf("LookupNames of %s failed - %s\n", lsa_name.string,
+ nt_errstr(status));
talloc_free(tmp_ctx);
- return False;
+ return NULL;
}
result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetUserName failed - %s\n", nt_errstr(status));
+ printf("(%s) GetUserName failed - %s\n",
+ __location__, nt_errstr(status));
talloc_free(lsa);
return NULL;
}
status = smb_raw_tcon(result, tmp_ctx, &tcon);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("smb_raw_tcon failed: %s\n", nt_errstr(status));
+ d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
+ nt_errstr(status));
talloc_free(tmp_ctx);
return status;
}
}
status = smbcli_full_connection(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL, cmdline_credentials, NULL);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("smbcli_full_connection failed: %s\n",
- nt_errstr(status));
+ d_printf("(%s) smbcli_full_connection failed: %s\n",
+ __location__, nt_errstr(status));
ret = False;
goto done;
}
if (!(user_sid = whoami(mem_ctx, cli->tree))) {
- d_printf("whoami on auth'ed connection failed\n");
+ d_printf("(%s) whoami on auth'ed connection failed\n",
+ __location__);
ret = False;
}
talloc_free(cli);
if (!(anon_creds = create_anon_creds(mem_ctx))) {
- d_printf("create_anon_creds failed\n");
+ d_printf("(%s) create_anon_creds failed\n", __location__);
ret = False;
goto done;
}
status = smbcli_full_connection(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL, anon_creds, NULL);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("anon smbcli_full_connection failed: %s\n",
- nt_errstr(status));
+ d_printf("(%s) anon smbcli_full_connection failed: %s\n",
+ __location__, nt_errstr(status));
ret = False;
goto done;
}
if (!(user_sid = whoami(mem_ctx, cli->tree))) {
- d_printf("whoami on anon connection failed\n");
+ d_printf("(%s) whoami on anon connection failed\n",
+ __location__);
ret = False;
goto done;
}
if (!dom_sid_equal(user_sid,
dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
- d_printf("Anon lsa_GetUserName returned %s, expected S-1-5-7",
+ d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
+ "S-1-5-7", __location__,
dom_sid_string(mem_ctx, user_sid));
ret = False;
}
if (!(user_creds = cli_credentials_init(mem_ctx))) {
- d_printf("cli_credentials_init failed\n");
+ d_printf("(%s) cli_credentials_init failed\n", __location__);
ret = False;
goto done;
}
cli_credentials_get_username(user_creds),
cli_credentials_get_password(user_creds),
&domain_name, &created_sid)) {
- d_printf("create_user failed\n");
+ d_printf("(%s) create_user failed\n", __location__);
ret = False;
goto done;
}
session2 = smbcli_session_init(cli->transport, mem_ctx, False);
if (session2 == NULL) {
- d_printf("smbcli_session_init failed\n");
+ d_printf("(%s) smbcli_session_init failed\n",
+ __location__);
goto done;
}
status = smb_composite_sesssetup(session2, &setup);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("anon session setup failed: %s\n",
- nt_errstr(status));
+ d_printf("(%s) session setup with new user failed: "
+ "%s\n", __location__, nt_errstr(status));
ret = False;
goto done;
}
+ session2->vuid = setup.out.vuid;
if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
"IPC$", &tree))) {
- d_printf("secondary_tcon failed\n");
+ d_printf("(%s) secondary_tcon failed\n",
+ __location__);
ret = False;
goto done;
}
if (!(user_sid = whoami(mem_ctx, tree))) {
- d_printf("whoami on user connection failed\n");
+ d_printf("(%s) whoami on user connection failed\n",
+ __location__);
ret = False;
goto delete;
}
delete:
if (!delete_user(cli, cmdline_credentials,
cli_credentials_get_username(user_creds))) {
- d_printf("delete_user failed\n");
+ d_printf("(%s) delete_user failed\n", __location__);
ret = False;
}
}
if (!(torture_open_connection_share(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL))) {
talloc_free(mem_ctx);
return False;
status = smbcli_mkdir(tree, "sharesec_testdir");
if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
- d_printf("Expected %s, got %s\n", nt_errstr(expected_mkdir),
- nt_errstr(status));
+ d_printf("(%s) Expected %s, got %s\n", __location__,
+ nt_errstr(expected_mkdir), nt_errstr(status));
ret = False;
}
}
if (!(torture_open_connection_share(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL))) {
d_printf("IPC$ connection failed\n");
talloc_free(mem_ctx);
return False;
}
- sd = get_sharesec(mem_ctx, cli->session, lp_parm_string(-1, "torture",
- "share"));
+ sd = get_sharesec(mem_ctx, cli->session, torture_setting_string(torture,
+ "share", NULL));
ret &= try_tcon(mem_ctx, sd, cli->session,
- lp_parm_string(-1, "torture", "share"),
+ torture_setting_string(torture, "share", NULL),
user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
ret &= try_tcon(mem_ctx, sd, cli->session,
- lp_parm_string(-1, "torture", "share"),
+ torture_setting_string(torture, "share", NULL),
user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
- NT_STATUS_NETWORK_ACCESS_DENIED);
+ NT_STATUS_MEDIA_WRITE_PROTECTED);
ret &= try_tcon(mem_ctx, sd, cli->session,
- lp_parm_string(-1, "torture", "share"),
+ torture_setting_string(torture, "share", NULL),
user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
talloc_free(mem_ctx);
}
if (!(torture_open_connection_share(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL))) {
d_printf("IPC$ connection failed\n");
talloc_free(mem_ctx);
return ret;
}
+static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
+ char **name)
+{
+ struct rap_WserverGetInfo r;
+ NTSTATUS status;
+ char servername[17];
+
+ r.in.level = 0;
+ r.in.bufsize = 0xffff;
+
+ status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ memcpy(servername, r.out.info.info0.name, 16);
+ servername[16] = '\0';
+
+ if (pull_ascii_talloc(mem_ctx, name, servername) < 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
const char ***printers, int *num_printers)
{
return NT_STATUS_OK;
}
+static BOOL enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
+ const char *servername, int level, int *num_printers)
+{
+ struct spoolss_EnumPrinters r;
+ NTSTATUS status;
+ DATA_BLOB blob;
+
+ r.in.flags = PRINTER_ENUM_LOCAL;
+ r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+
+ status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
+ __location__, nt_errstr(status));
+ return False;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ d_printf("(%s) EnumPrinters unexpected return code %s, should "
+ "be WERR_INSUFFICIENT_BUFFER\n", __location__,
+ win_errstr(r.out.result));
+ return False;
+ }
+
+ blob = data_blob_talloc_zero(mem_ctx, r.out.needed);
+ if (blob.data == NULL) {
+ d_printf("(%s) data_blob_talloc failed\n", __location__);
+ return False;
+ }
+
+ r.in.buffer = &blob;
+ r.in.offered = r.out.needed;
+
+ status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+ d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
+ "%s\n", __location__, nt_errstr(status),
+ win_errstr(r.out.result));
+ return False;
+ }
+
+ *num_printers = r.out.count;
+
+ return True;
+}
+
static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
struct policy_handle *handle, int level,
union spoolss_PrinterInfo **res)
talloc_free(mem_ctx);
return NT_STATUS_OK;
}
-
BOOL torture_samba3_rpc_spoolss(struct torture_context *torture)
{
const char **printers;
int num_printers;
struct spoolss_UserLevel1 userlevel1;
+ char *servername;
if (!(mem_ctx = talloc_new(torture))) {
return False;
}
if (!(torture_open_connection_share(
- mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
"IPC$", NULL))) {
d_printf("IPC$ connection failed\n");
talloc_free(mem_ctx);
return False;
}
+ status = get_servername(mem_ctx, cli->tree, &servername);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "(%s) get_servername returned %s\n",
+ __location__, nt_errstr(status));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
&printers, &num_printers))) {
talloc_free(mem_ctx);
struct spoolss_OpenPrinterEx r;
ZERO_STRUCT(r);
- r.in.printername = talloc_asprintf(
- mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
+ servername);
r.in.datatype = NULL;
r.in.access_mask = 0;
r.in.level = 1;
r.out.handle = &server_handle;
status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
- "%s\n", __location__, nt_errstr(status));
+ "%s, %s\n", __location__, nt_errstr(status),
+ win_errstr(r.out.result));
talloc_free(mem_ctx);
return False;
}
r.out.handle = &server_handle;
status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
- "%s\n", __location__, nt_errstr(status));
+ "%s, %s\n", __location__, nt_errstr(status),
+ win_errstr(r.out.result));
talloc_free(mem_ctx);
return False;
}
ZERO_STRUCT(r);
r.in.printername = talloc_asprintf(
- mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p),
- printers[0]);
+ mem_ctx, "\\\\%s\\%s", servername, printers[0]);
r.in.datatype = NULL;
r.in.access_mask = 0;
r.in.level = 1;
r.out.handle = &printer_handle;
status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
- "%s\n", __location__, nt_errstr(status));
+ "%s, %s\n", __location__, nt_errstr(status),
+ win_errstr(r.out.result));
talloc_free(mem_ctx);
return False;
}
}
}
+ {
+ int num_enumerated;
+ if (!enumprinters(mem_ctx, p, servername, 1,
+ &num_enumerated)) {
+ d_printf("(%s) enumprinters failed\n", __location__);
+ talloc_free(mem_ctx);
+ return False;
+ }
+ if (num_printers != num_enumerated) {
+ d_printf("(%s) netshareenum gave %d printers, "
+ "enumprinters lvl 1 gave %d\n", __location__,
+ num_printers, num_enumerated);
+ talloc_free(mem_ctx);
+ return False;
+ }
+ }
+
+ {
+ int num_enumerated;
+ if (!enumprinters(mem_ctx, p, servername, 2,
+ &num_enumerated)) {
+ d_printf("(%s) enumprinters failed\n", __location__);
+ talloc_free(mem_ctx);
+ return False;
+ }
+ if (num_printers != num_enumerated) {
+ d_printf("(%s) netshareenum gave %d printers, "
+ "enumprinters lvl 2 gave %d\n", __location__,
+ num_printers, num_enumerated);
+ talloc_free(mem_ctx);
+ return False;
+ }
+ }
+
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+BOOL torture_samba3_rpc_wkssvc(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx;
+ struct smbcli_state *cli;
+ struct dcerpc_pipe *p;
+ NTSTATUS status;
+ char *servername;
+
+ if (!(mem_ctx = talloc_new(torture))) {
+ return False;
+ }
+
+ if (!(torture_open_connection_share(
+ mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
+ "IPC$", NULL))) {
+ d_printf("IPC$ connection failed\n");
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ status = get_servername(mem_ctx, cli->tree, &servername);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "(%s) get_servername returned %s\n",
+ __location__, nt_errstr(status));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ status = pipe_bind_smb(mem_ctx, cli->tree, "\\wkssvc",
+ &dcerpc_table_wkssvc, &p);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
+ nt_errstr(status));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ {
+ struct wkssvc_NetWkstaInfo100 wks100;
+ union wkssvc_NetWkstaInfo info;
+ struct wkssvc_NetWkstaGetInfo r;
+
+ r.in.server_name = "\\foo";
+ r.in.level = 100;
+ info.info100 = &wks100;
+ r.out.info = &info;
+
+ status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+ d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
+ "%s, %s\n", __location__, nt_errstr(status),
+ win_errstr(r.out.result));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ if (strcmp(servername,
+ r.out.info->info100->server_name) != 0) {
+ d_printf("(%s) servername inconsistency: RAP=%s, "
+ "dcerpc_wkssvc_NetWksGetInfo=%s",
+ __location__, servername,
+ r.out.info->info100->server_name);
+ talloc_free(mem_ctx);
+ return False;
+ }
+ }
+
+ talloc_free(mem_ctx);
+ return True;
+}
+
+static NTSTATUS winreg_close(struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct winreg_CloseKey c;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+
+ c.in.handle = c.out.handle = handle;
+
+ if (!(mem_ctx = talloc_new(p))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
+ talloc_free(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!W_ERROR_IS_OK(c.out.result)) {
+ return werror_to_ntstatus(c.out.result);
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
+ TALLOC_CTX *mem_ctx)
+{
+ uint32_t enum_index = 0;
+
+ while (1) {
+ struct winreg_EnumValue r;
+ struct winreg_StringBuf name;
+ enum winreg_Type type = 0;
+ uint8_t buf8[1024];
+ NTSTATUS status;
+ uint32_t size, length;
+
+ r.in.handle = handle;
+ r.in.enum_index = enum_index;
+ name.name = "";
+ name.size = 1024;
+ r.in.name = r.out.name = &name;
+ size = 1024;
+ length = 5;
+ r.in.type = &type;
+ r.in.value = buf8;
+ r.in.size = &size;
+ r.in.length = &length;
+
+ status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+ return NT_STATUS_OK;
+ }
+ enum_index += 1;
+ }
+}
+
+static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
+ TALLOC_CTX *mem_ctx, int depth)
+{
+ struct winreg_EnumKey r;
+ struct winreg_StringBuf class, name;
+ NTSTATUS status;
+ NTTIME t = 0;
+
+ if (depth <= 0) {
+ return NT_STATUS_OK;
+ }
+
+ class.name = "";
+ class.size = 1024;
+
+ r.in.handle = handle;
+ r.in.enum_index = 0;
+ r.in.name = &name;
+ r.in.keyclass = &class;
+ r.out.name = &name;
+ r.in.last_changed_time = &t;
+
+ do {
+ TALLOC_CTX *tmp_ctx;
+ struct winreg_OpenKey o;
+ struct policy_handle key_handle;
+ int i;
+
+ if (!(tmp_ctx = talloc_new(mem_ctx))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ name.name = NULL;
+ name.size = 1024;
+
+ status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+ /* We're done enumerating */
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
+ for (i=0; i<10-depth; i++)
+ printf(" ");
+ printf("%s\n", r.out.name->name);
+
+
+ o.in.parent_handle = handle;
+ o.in.keyname.name = r.out.name->name;
+ o.in.unknown = 0;
+ o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ o.out.handle = &key_handle;
+
+ status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
+ if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
+ enumkeys(p, &key_handle, tmp_ctx, depth-1);
+ enumvalues(p, &key_handle, tmp_ctx);
+ status = winreg_close(p, &key_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+
+ r.in.enum_index += 1;
+ } while(True);
+
+ return NT_STATUS_OK;
+}
+
+typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
+
+static BOOL test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ const char *name, winreg_open_fn open_fn)
+{
+ struct policy_handle handle;
+ struct winreg_OpenHKLM r;
+ NTSTATUS status;
+
+ r.in.system_name = 0;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.handle = &handle;
+
+ status = open_fn(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+ d_printf("(%s) %s failed: %s, %s\n", __location__, name,
+ nt_errstr(status), win_errstr(r.out.result));
+ return False;
+ }
+
+ enumkeys(p, &handle, mem_ctx, 4);
+
+ status = winreg_close(p, &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) dcerpc_CloseKey failed: %s\n",
+ __location__, nt_errstr(status));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL torture_samba3_rpc_winreg(struct torture_context *torture)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *mem_ctx;
+ BOOL ret = True;
+ struct {
+ const char *name;
+ winreg_open_fn fn;
+ } open_fns[] = {
+ {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
+ {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
+ {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
+ {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
+ {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
+#if 0
+ int i;
+#endif
+
+ mem_ctx = talloc_init("torture_rpc_winreg");
+
+ status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_winreg);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+#if 1
+ ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
+#else
+ for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
+ if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
+ ret = False;
+ }
+#endif
+
talloc_free(mem_ctx);
return ret;