summaryrefslogtreecommitdiff
path: root/source4/torture/rpc/samba3rpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/rpc/samba3rpc.c')
-rw-r--r--source4/torture/rpc/samba3rpc.c324
1 files changed, 275 insertions, 49 deletions
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index 503126b153..f1379e247f 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -324,10 +324,11 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
struct cli_credentials *admin_creds,
uint8_t auth_type,
uint8_t auth_level,
- const char *wks_name,
+ const char *username,
char **domain,
struct dcerpc_pipe **result_pipe,
- struct policy_handle **result_handle)
+ struct policy_handle **result_handle,
+ struct dom_sid **sid)
{
struct dcerpc_pipe *samr_pipe;
NTSTATUS status;
@@ -434,9 +435,9 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
}
c.in.domain_handle = &domain_handle;
- user_name.string = talloc_asprintf(mem_ctx, "%s$", wks_name);
+ user_name.string = username;
c.in.account_name = &user_name;
- c.in.acct_flags = ACB_WSTRUST;
+ c.in.acct_flags = ACB_NORMAL;
c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
user_handle = talloc(mem_ctx, struct policy_handle);
c.out.user_handle = user_handle;
@@ -462,7 +463,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
ou.in.domain_handle = &domain_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ user_rid = ou.in.rid = ln.out.rids.ids[0];
ou.out.user_handle = user_handle;
status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
@@ -480,6 +481,9 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
*result_pipe = samr_pipe;
*result_handle = user_handle;
+ if (sid != NULL) {
+ *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
+ }
return NT_STATUS_OK;
fail:
@@ -487,6 +491,163 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
}
/*
+ * Create a test user
+ */
+
+static BOOL create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
+ struct cli_credentials *admin_creds,
+ const char *username, const char *password,
+ char **domain_name,
+ struct dom_sid **user_sid)
+{
+ TALLOC_CTX *tmp_ctx;
+ NTSTATUS status;
+ struct dcerpc_pipe *samr_pipe;
+ struct policy_handle *wks_handle;
+ BOOL ret = False;
+
+ if (!(tmp_ctx = talloc_new(mem_ctx))) {
+ d_printf("talloc_init failed\n");
+ return False;
+ }
+
+ status = get_usr_handle(cli, tmp_ctx, admin_creds,
+ DCERPC_AUTH_TYPE_NTLMSSP,
+ DCERPC_AUTH_LEVEL_INTEGRITY,
+ username, domain_name, &samr_pipe, &wks_handle,
+ user_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
+ goto done;
+ }
+
+ {
+ struct samr_SetUserInfo2 sui2;
+ struct samr_SetUserInfo sui;
+ struct samr_QueryUserInfo qui;
+ union samr_UserInfo u_info;
+ DATA_BLOB session_key;
+
+ encode_pw_buffer(u_info.info24.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,
+ &session_key);
+ sui2.in.user_handle = wks_handle;
+ sui2.in.info = &u_info;
+ sui2.in.level = 24;
+
+ status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("samr_SetUserInfo(24) failed: %s\n",
+ nt_errstr(status));
+ goto done;
+ }
+
+ u_info.info16.acct_flags = ACB_NORMAL;
+ sui.in.user_handle = wks_handle;
+ sui.in.info = &u_info;
+ sui.in.level = 16;
+
+ status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("samr_SetUserInfo(16) failed\n");
+ goto done;
+ }
+
+ qui.in.user_handle = wks_handle;
+ qui.in.level = 21;
+
+ status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("samr_QueryUserInfo(21) failed\n");
+ goto done;
+ }
+
+ qui.out.info->info21.allow_password_change = 0;
+ 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.fields_present = 0x81827fa; /* copy usrmgr.exe */
+
+ u_info.info21 = qui.out.info->info21;
+ sui.in.user_handle = wks_handle;
+ sui.in.info = &u_info;
+ sui.in.level = 21;
+
+ status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("samr_SetUserInfo(21) failed\n");
+ goto done;
+ }
+ }
+
+ *domain_name= talloc_steal(mem_ctx, *domain_name);
+ *user_sid = talloc_steal(mem_ctx, *user_sid);
+ ret = True;
+ done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/*
+ * Delete a test user
+ */
+
+static BOOL delete_user(struct smbcli_state *cli,
+ struct cli_credentials *admin_creds,
+ const char *username)
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS status;
+ char *dom_name;
+ struct dcerpc_pipe *samr_pipe;
+ struct policy_handle *user_handle;
+ BOOL ret = False;
+
+ if ((mem_ctx = talloc_init("leave")) == NULL) {
+ d_printf("talloc_init failed\n");
+ return False;
+ }
+
+ status = get_usr_handle(cli, mem_ctx, admin_creds,
+ DCERPC_AUTH_TYPE_NTLMSSP,
+ DCERPC_AUTH_LEVEL_INTEGRITY,
+ username, &dom_name, &samr_pipe,
+ &user_handle, NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
+ goto done;
+ }
+
+ {
+ struct samr_DeleteUser d;
+
+ d.in.user_handle = user_handle;
+ d.out.user_handle = user_handle;
+
+ status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("samr_DeleteUser failed\n");
+ goto done;
+ }
+ }
+
+ ret = True;
+
+ done:
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+/*
* Do a Samba3-style join
*/
@@ -507,11 +668,13 @@ static BOOL join3(struct smbcli_state *cli,
return False;
}
- status = get_usr_handle(cli, mem_ctx, admin_creds,
- DCERPC_AUTH_TYPE_NTLMSSP,
- DCERPC_AUTH_LEVEL_PRIVACY,
- cli_credentials_get_workstation(wks_creds),
- &dom_name, &samr_pipe, &wks_handle);
+ status = get_usr_handle(
+ cli, mem_ctx, admin_creds,
+ DCERPC_AUTH_TYPE_NTLMSSP,
+ DCERPC_AUTH_LEVEL_PRIVACY,
+ talloc_asprintf(mem_ctx, "%s$",
+ cli_credentials_get_workstation(wks_creds)),
+ &dom_name, &samr_pipe, &wks_handle, NULL);
if (!NT_STATUS_IS_OK(status)) {
d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
@@ -930,46 +1093,12 @@ static BOOL leave(struct smbcli_state *cli,
struct cli_credentials *admin_creds,
struct cli_credentials *wks_creds)
{
- TALLOC_CTX *mem_ctx;
- NTSTATUS status;
- char *dom_name;
- struct dcerpc_pipe *samr_pipe;
- struct policy_handle *wks_handle;
- BOOL ret = False;
-
- if ((mem_ctx = talloc_init("leave")) == NULL) {
- d_printf("talloc_init failed\n");
- return False;
- }
-
- status = get_usr_handle(cli, mem_ctx, admin_creds,
- DCERPC_AUTH_TYPE_NTLMSSP,
- DCERPC_AUTH_LEVEL_PRIVACY,
- cli_credentials_get_workstation(wks_creds),
- &dom_name, &samr_pipe, &wks_handle);
-
- if (!NT_STATUS_IS_OK(status)) {
- d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
- goto done;
- }
-
- {
- struct samr_DeleteUser d;
-
- d.in.user_handle = wks_handle;
- d.out.user_handle = wks_handle;
-
- status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
- if (!NT_STATUS_IS_OK(status)) {
- d_printf("samr_DeleteUser failed\n");
- goto done;
- }
- }
-
- ret = True;
+ char *wks_name = talloc_asprintf(
+ NULL, "%s$", cli_credentials_get_workstation(wks_creds));
+ BOOL ret;
- done:
- talloc_free(mem_ctx);
+ ret = delete_user(cli, admin_creds, wks_name);
+ talloc_free(wks_name);
return ret;
}
@@ -1394,7 +1523,10 @@ BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
TALLOC_CTX *mem_ctx;
BOOL ret = True;
struct dom_sid *user_sid;
+ struct dom_sid *created_sid;
struct cli_credentials *anon_creds;
+ struct cli_credentials *user_creds;
+ char *domain_name;
if (!(mem_ctx = talloc_new(torture))) {
return False;
@@ -1446,6 +1578,99 @@ BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
ret = False;
}
+ if (!(user_creds = cli_credentials_init(mem_ctx))) {
+ d_printf("cli_credentials_init failed\n");
+ ret = False;
+ goto done;
+ }
+
+ cli_credentials_set_conf(user_creds);
+ cli_credentials_set_username(user_creds, "torture_username",
+ CRED_SPECIFIED);
+ cli_credentials_set_password(user_creds,
+ generate_random_str(user_creds, 8),
+ CRED_SPECIFIED);
+
+ if (!create_user(mem_ctx, cli, cmdline_credentials,
+ cli_credentials_get_username(user_creds),
+ cli_credentials_get_password(user_creds),
+ &domain_name, &created_sid)) {
+ d_printf("create_user failed\n");
+ ret = False;
+ goto done;
+ }
+
+ cli_credentials_set_domain(user_creds, domain_name,
+ CRED_SPECIFIED);
+
+ {
+ struct smbcli_session *session2;
+ struct smb_composite_sesssetup setup;
+ struct smbcli_tree *tree;
+ union smb_tcon tcon;
+
+ session2 = smbcli_session_init(cli->transport, mem_ctx, False);
+ if (session2 == NULL) {
+ d_printf("smbcli_session_init failed\n");
+ goto done;
+ }
+
+ setup.in.sesskey = cli->transport->negotiate.sesskey;
+ setup.in.capabilities = cli->transport->negotiate.capabilities;
+ setup.in.workgroup = "";
+ setup.in.credentials = user_creds;
+
+ status = smb_composite_sesssetup(session2, &setup);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("anon session setup failed: %s\n",
+ nt_errstr(status));
+ ret = False;
+ goto done;
+ }
+
+ if (!(tree = smbcli_tree_init(session2, mem_ctx, False))) {
+ d_printf("smbcli_tree_init failed\n");
+ ret = False;
+ goto done;
+ }
+
+ tcon.generic.level = RAW_TCON_TCONX;
+ tcon.tconx.in.flags = 0;
+ tcon.tconx.in.password = data_blob(NULL, 0);
+ tcon.tconx.in.path = "IPC$";
+ tcon.tconx.in.device = "?????";
+
+ status = smb_raw_tcon(tree, mem_ctx, &tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("smb_raw_tcon failed\n");
+ ret = False;
+ goto done;
+ }
+
+ tree->tid = tcon.tconx.out.tid;
+
+ if (!(user_sid = whoami(mem_ctx, tree))) {
+ d_printf("whoami on user connection failed\n");
+ ret = False;
+ goto delete;
+ }
+ }
+
+ d_printf("Created %s, found %s\n",
+ dom_sid_string(mem_ctx, created_sid),
+ dom_sid_string(mem_ctx, user_sid));
+
+ if (!dom_sid_equal(created_sid, user_sid)) {
+ ret = False;
+ }
+
+ delete:
+ if (!delete_user(cli, cmdline_credentials,
+ cli_credentials_get_username(user_creds))) {
+ d_printf("delete_user failed\n");
+ ret = False;
+ }
+
done:
talloc_free(mem_ctx);
return ret;
@@ -1570,6 +1795,7 @@ BOOL torture_samba3_rpc_srvsvc(struct torture_context *torture)
} else {
ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
}
+
done:
talloc_free(mem_ctx);
return ret;