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
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.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 "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));
union samr_UserInfo u_info;
DATA_BLOB session_key;
- encode_pw_buffer(u_info.info24.password.data, password,
+
+ ZERO_STRUCT(u_info);
+ encode_pw_buffer(u_info.info23.password.data, password,
STR_UNICODE);
- u_info.info24.pw_len = strlen_m(password)*2;
status = dcerpc_fetch_session_key(samr_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
d_printf("dcerpc_fetch_session_key failed\n");
goto done;
}
- arcfour_crypt_blob(u_info.info24.password.data, 516,
+ arcfour_crypt_blob(u_info.info23.password.data, 516,
&session_key);
+ u_info.info23.info.password_expired = 0;
+ u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG;
sui2.in.user_handle = wks_handle;
sui2.in.info = &u_info;
- sui2.in.level = 24;
+ sui2.in.level = 23;
status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("samr_SetUserInfo(24) failed: %s\n",
+ d_printf("samr_SetUserInfo(23) failed: %s\n",
nt_errstr(status));
goto done;
}
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 NULL;
}
}
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("(%s) smbcli_full_connection failed: %s\n",
}
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("(%s) anon smbcli_full_connection failed: %s\n",
ret = False;
goto done;
}
+ session2->vuid = setup.out.vuid;
if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
"IPC$", &tree))) {
}
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 False;
}
- blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
+ 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;
}
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);
}
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);
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;
+}