Beispiel #1
0
NTSTATUS torture_delete_testuser(struct torture_context *torture,
				 struct test_join *join,
				 const char *username)
{
	NTSTATUS status;

	status = DeleteUser_byname(join->p->binding_handle,
				   torture,
				   &join->domain_handle,
				   username);

	return status;
}
Beispiel #2
0
struct test_join *torture_create_testuser(struct torture_context *torture,
					  const char *username, 
					  const char *domain,
					  uint16_t acct_type,
					  const char **random_password)
{
	NTSTATUS status;
	struct samr_Connect c;
	struct samr_CreateUser2 r;
	struct samr_OpenDomain o;
	struct samr_LookupDomain l;
	struct dom_sid2 *sid = NULL;
	struct samr_GetUserPwInfo pwp;
	struct samr_PwInfo info;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	struct policy_handle handle;
	struct policy_handle domain_handle;
	uint32_t access_granted;
	uint32_t rid;
	DATA_BLOB session_key;
	struct lsa_String name;
	
	int policy_min_pw_len = 0;
	struct test_join *join;
	char *random_pw;
	const char *dc_binding = torture_setting_string(torture, "dc_binding", NULL);

	join = talloc(NULL, struct test_join);
	if (join == NULL) {
		return NULL;
	}

	ZERO_STRUCTP(join);

	printf("Connecting to SAMR\n");
	
	if (dc_binding) {
		status = dcerpc_pipe_connect(join,
					     &join->p,
					     dc_binding,
					     &ndr_table_samr,
					     cmdline_credentials, NULL, torture->lp_ctx);
					     
	} else {
		status = torture_rpc_connection(torture, 
						&join->p, 
						&ndr_table_samr);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}

	c.in.system_name = NULL;
	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	c.out.connect_handle = &handle;

	status = dcerpc_samr_Connect(join->p, join, &c);
	if (!NT_STATUS_IS_OK(status)) {
		const char *errstr = nt_errstr(status);
		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
			errstr = dcerpc_errstr(join, join->p->last_fault_code);
		}
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}

	printf("Opening domain %s\n", domain);

	name.string = domain;
	l.in.connect_handle = &handle;
	l.in.domain_name = &name;
	l.out.sid = &sid;

	status = dcerpc_samr_LookupDomain(join->p, join, &l);
	if (!NT_STATUS_IS_OK(status)) {
		printf("LookupDomain failed - %s\n", nt_errstr(status));
		goto failed;
	}

	talloc_steal(join, *l.out.sid);
	join->dom_sid = *l.out.sid;
	join->dom_netbios_name = talloc_strdup(join, domain);
	if (!join->dom_netbios_name) goto failed;

	o.in.connect_handle = &handle;
	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	o.in.sid = *l.out.sid;
	o.out.domain_handle = &domain_handle;

	status = dcerpc_samr_OpenDomain(join->p, join, &o);
	if (!NT_STATUS_IS_OK(status)) {
		printf("OpenDomain failed - %s\n", nt_errstr(status));
		goto failed;
	}

	printf("Creating account %s\n", username);

again:
	name.string = username;
	r.in.domain_handle = &domain_handle;
	r.in.account_name = &name;
	r.in.acct_flags = acct_type;
	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	r.out.user_handle = &join->user_handle;
	r.out.access_granted = &access_granted;
	r.out.rid = &rid;

	status = dcerpc_samr_CreateUser2(join->p, join, &r);

	if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
		status = DeleteUser_byname(join->p, join, &domain_handle, name.string);
		if (NT_STATUS_IS_OK(status)) {
			goto again;
		}
	}

	if (!NT_STATUS_IS_OK(status)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(status));
		goto failed;
	}

	join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);

	pwp.in.user_handle = &join->user_handle;
	pwp.out.info = &info;

	status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
	if (NT_STATUS_IS_OK(status)) {
		policy_min_pw_len = pwp.out.info->min_password_length;
	}

	random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));

	printf("Setting account password '%s'\n", random_pw);

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 24;

	encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
	u.info24.password_expired = 0;

	status = dcerpc_fetch_session_key(join->p, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo level %u - no session key - %s\n",
		       s.in.level, nt_errstr(status));
		torture_leave_domain(torture, join);
		goto failed;
	}

	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);

	status = dcerpc_samr_SetUserInfo(join->p, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.acct_flags = acct_type | ACB_PWNOEXP;
	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;

	u.info21.comment.string = talloc_asprintf(join, 
						  "Tortured by Samba4: %s", 
						  timestring(join, time(NULL)));
	
	u.info21.full_name.string = talloc_asprintf(join, 
						    "Torture account for Samba4: %s", 
						    timestring(join, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(join, 
					 "Samba4 torture account created by host %s: %s", 
					 lp_netbios_name(torture->lp_ctx), 
					 timestring(join, time(NULL)));

	printf("Resetting ACB flags, force pw change time\n");

	status = dcerpc_samr_SetUserInfo(join->p, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}

	if (random_password) {
		*random_password = random_pw;
	}

	return join;

failed:
	torture_leave_domain(torture, join);
	return NULL;
}
Beispiel #3
0
struct test_join *torture_create_testuser_max_pwlen(struct torture_context *torture,
						    const char *username,
						    const char *domain,
						    uint16_t acct_type,
						    const char **random_password,
						    int max_pw_len)
{
	NTSTATUS status;
	struct samr_Connect c;
	struct samr_CreateUser2 r;
	struct samr_OpenDomain o;
	struct samr_LookupDomain l;
	struct dom_sid2 *sid = NULL;
	struct samr_GetUserPwInfo pwp;
	struct samr_PwInfo info;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	struct policy_handle handle;
	uint32_t access_granted;
	uint32_t rid;
	DATA_BLOB session_key;
	struct lsa_String name;
	
	int policy_min_pw_len = 0;
	struct test_join *join;
	char *random_pw;
	const char *dc_binding = torture_setting_string(torture, "dc_binding", NULL);
	struct dcerpc_binding_handle *b = NULL;

	join = talloc(NULL, struct test_join);
	if (join == NULL) {
		return NULL;
	}

	ZERO_STRUCTP(join);

	printf("Connecting to SAMR\n");
	
	if (dc_binding) {
		status = dcerpc_pipe_connect(join,
					     &join->p,
					     dc_binding,
					     &ndr_table_samr,
					     cmdline_credentials, NULL, torture->lp_ctx);
					     
	} else {
		status = torture_rpc_connection(torture, 
						&join->p, 
						&ndr_table_samr);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}
	b = join->p->binding_handle;

	c.in.system_name = NULL;
	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	c.out.connect_handle = &handle;

	status = dcerpc_samr_Connect_r(b, join, &c);
	if (!NT_STATUS_IS_OK(status)) {
		const char *errstr = nt_errstr(status);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}
	if (!NT_STATUS_IS_OK(c.out.result)) {
		const char *errstr = nt_errstr(c.out.result);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}

	if (domain) {
		printf("Opening domain %s\n", domain);

		name.string = domain;
		l.in.connect_handle = &handle;
		l.in.domain_name = &name;
		l.out.sid = &sid;

		status = dcerpc_samr_LookupDomain_r(b, join, &l);
		if (!NT_STATUS_IS_OK(status)) {
			printf("LookupDomain failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(l.out.result)) {
			printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
			goto failed;
		}
	} else {
		struct samr_EnumDomains e;
		uint32_t resume_handle = 0, num_entries;
		struct samr_SamArray *sam;
		int i;

		e.in.connect_handle = &handle;
		e.in.buf_size = (uint32_t)-1;
		e.in.resume_handle = &resume_handle;
		e.out.sam = &sam;
		e.out.num_entries = &num_entries;
		e.out.resume_handle = &resume_handle;

		status = dcerpc_samr_EnumDomains_r(b, join, &e);
		if (!NT_STATUS_IS_OK(status)) {
			printf("EnumDomains failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(e.out.result)) {
			printf("EnumDomains failed - %s\n", nt_errstr(e.out.result));
			goto failed;
		}
		if ((num_entries != 2) || (sam && sam->count != 2)) {
			printf("unexpected number of domains\n");
			goto failed;
		}
		for (i=0; i < 2; i++) {
			if (!strequal(sam->entries[i].name.string, "builtin")) {
				domain = sam->entries[i].name.string;
				break;
			}
		}
		if (domain) {
			printf("Opening domain %s\n", domain);

			name.string = domain;
			l.in.connect_handle = &handle;
			l.in.domain_name = &name;
			l.out.sid = &sid;

			status = dcerpc_samr_LookupDomain_r(b, join, &l);
			if (!NT_STATUS_IS_OK(status)) {
				printf("LookupDomain failed - %s\n", nt_errstr(status));
				goto failed;
			}
			if (!NT_STATUS_IS_OK(l.out.result)) {
				printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
				goto failed;
			}
		} else {
			printf("cannot proceed without domain name\n");
			goto failed;
		}
	}

	talloc_steal(join, *l.out.sid);
	join->dom_sid = *l.out.sid;
	join->dom_netbios_name = talloc_strdup(join, domain);
	if (!join->dom_netbios_name) goto failed;

	o.in.connect_handle = &handle;
	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	o.in.sid = *l.out.sid;
	o.out.domain_handle = &join->domain_handle;

	status = dcerpc_samr_OpenDomain_r(b, join, &o);
	if (!NT_STATUS_IS_OK(status)) {
		printf("OpenDomain failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(o.out.result)) {
		printf("OpenDomain failed - %s\n", nt_errstr(o.out.result));
		goto failed;
	}

	printf("Creating account %s\n", username);

again:
	name.string = username;
	r.in.domain_handle = &join->domain_handle;
	r.in.account_name = &name;
	r.in.acct_flags = acct_type;
	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	r.out.user_handle = &join->user_handle;
	r.out.access_granted = &access_granted;
	r.out.rid = &rid;

	status = dcerpc_samr_CreateUser2_r(b, join, &r);
	if (!NT_STATUS_IS_OK(status)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(status));
		goto failed;
	}

	if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
		status = DeleteUser_byname(b, join, &join->domain_handle, name.string);
		if (NT_STATUS_IS_OK(status)) {
			goto again;
		}
	}

	if (!NT_STATUS_IS_OK(r.out.result)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(r.out.result));
		goto failed;
	}

	join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);

	pwp.in.user_handle = &join->user_handle;
	pwp.out.info = &info;

	status = dcerpc_samr_GetUserPwInfo_r(b, join, &pwp);
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(pwp.out.result)) {
		policy_min_pw_len = pwp.out.info->min_password_length;
	}

	random_pw = generate_random_password(join, MAX(8, policy_min_pw_len), max_pw_len);

	printf("Setting account password '%s'\n", random_pw);

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 24;

	encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
	u.info24.password_expired = 0;

	status = dcerpc_fetch_session_key(join->p, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo level %u - no session key - %s\n",
		       s.in.level, nt_errstr(status));
		torture_leave_domain(torture, join);
		goto failed;
	}

	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.acct_flags = acct_type | ACB_PWNOEXP;
	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;

	u.info21.comment.string = talloc_asprintf(join, 
						  "Tortured by Samba4: %s", 
						  timestring(join, time(NULL)));
	
	u.info21.full_name.string = talloc_asprintf(join, 
						    "Torture account for Samba4: %s", 
						    timestring(join, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(join, 
					 "Samba4 torture account created by host %s: %s", 
					 lpcfg_netbios_name(torture->lp_ctx),
					 timestring(join, time(NULL)));

	printf("Resetting ACB flags, force pw change time\n");

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	if (random_password) {
		*random_password = random_pw;
	}

	return join;

failed:
	torture_leave_domain(torture, join);
	return NULL;
}