• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/torture/libnet/
1/*
2   Unix SMB/CIFS implementation.
3   Test suite for libnet calls.
4
5   Copyright (C) Rafal Szczesniak 2005
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22#include "torture/rpc/rpc.h"
23#include "torture/libnet/usertest.h"
24#include "libnet/libnet.h"
25#include "librpc/gen_ndr/ndr_samr_c.h"
26#include "param/param.h"
27
28#include "torture/libnet/utils.h"
29
30
31static bool test_useradd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
32			 struct policy_handle *domain_handle,
33			 const char *name)
34{
35	NTSTATUS status;
36	bool ret = true;
37	struct libnet_rpc_useradd user;
38
39	user.in.domain_handle = *domain_handle;
40	user.in.username      = name;
41
42	printf("Testing libnet_rpc_useradd\n");
43
44	status = libnet_rpc_useradd(p, mem_ctx, &user);
45	if (!NT_STATUS_IS_OK(status)) {
46		printf("Failed to call libnet_rpc_useradd - %s\n", nt_errstr(status));
47		return false;
48	}
49
50	return ret;
51}
52
53
54static bool test_useradd_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55			       struct policy_handle *handle, const char* username)
56{
57	NTSTATUS status;
58	struct composite_context *c;
59	struct libnet_rpc_useradd user;
60
61	user.in.domain_handle = *handle;
62	user.in.username      = username;
63
64	printf("Testing async libnet_rpc_useradd\n");
65
66	c = libnet_rpc_useradd_send(p, &user, msg_handler);
67	if (!c) {
68		printf("Failed to call async libnet_rpc_useradd\n");
69		return false;
70	}
71
72	status = libnet_rpc_useradd_recv(c, mem_ctx, &user);
73	if (!NT_STATUS_IS_OK(status)) {
74		printf("Calling async libnet_rpc_useradd failed - %s\n", nt_errstr(status));
75		return false;
76	}
77
78	return true;
79
80}
81
82static bool test_usermod(struct torture_context *tctx, struct dcerpc_pipe *p,
83			 TALLOC_CTX *mem_ctx,
84			 struct policy_handle *handle, int num_changes,
85			 struct libnet_rpc_usermod *mod, char **username)
86{
87	const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
88	const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
89	const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
90	const char *homedir, *homedrive, *logonscript;
91	const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL | ACB_PW_EXPIRED),
92				   (ACB_NORMAL | ACB_PWNOEXP),
93				   (ACB_NORMAL | ACB_PW_EXPIRED) };
94
95	NTSTATUS status;
96	struct timeval now;
97	enum test_fields testfld;
98	int i;
99
100	ZERO_STRUCT(*mod);
101	srandom((unsigned)time(NULL));
102
103	mod->in.username = talloc_strdup(mem_ctx, *username);
104	mod->in.domain_handle = *handle;
105
106	torture_comment(tctx, "modifying user (%d simultaneous change(s))\n",
107			num_changes);
108
109	torture_comment(tctx, "fields to change: [");
110
111	for (i = 0; i < num_changes && i < FIELDS_NUM - 1; i++) {
112		const char *fldname;
113
114		testfld = (random() % (FIELDS_NUM - 1)) + 1;
115
116		gettimeofday(&now, NULL);
117
118		switch (testfld) {
119		case account_name:
120			continue_if_field_set(mod->in.change.account_name);
121			mod->in.change.account_name = talloc_asprintf(mem_ctx, TEST_CHG_ACCOUNTNAME,
122								      (int)(random() % 100));
123			mod->in.change.fields |= USERMOD_FIELD_ACCOUNT_NAME;
124			fldname = "account_name";
125			*username = talloc_strdup(mem_ctx, mod->in.change.account_name);
126			break;
127
128		case full_name:
129			continue_if_field_set(mod->in.change.full_name);
130			mod->in.change.full_name = talloc_asprintf(mem_ctx, TEST_CHG_FULLNAME,
131								  (int)random(), (int)random());
132			mod->in.change.fields |= USERMOD_FIELD_FULL_NAME;
133			fldname = "full_name";
134			break;
135
136		case description:
137			continue_if_field_set(mod->in.change.description);
138			mod->in.change.description = talloc_asprintf(mem_ctx, TEST_CHG_DESCRIPTION,
139								    random());
140			mod->in.change.fields |= USERMOD_FIELD_DESCRIPTION;
141			fldname = "description";
142			break;
143
144		case home_directory:
145			continue_if_field_set(mod->in.change.home_directory);
146			homedir = home_dirs[random() % (sizeof(home_dirs)/sizeof(char*))];
147			mod->in.change.home_directory = talloc_strdup(mem_ctx, homedir);
148			mod->in.change.fields |= USERMOD_FIELD_HOME_DIRECTORY;
149			fldname = "home_directory";
150			break;
151
152		case home_drive:
153			continue_if_field_set(mod->in.change.home_drive);
154			homedrive = home_drives[random() % (sizeof(home_drives)/sizeof(char*))];
155			mod->in.change.home_drive = talloc_strdup(mem_ctx, homedrive);
156			mod->in.change.fields |= USERMOD_FIELD_HOME_DRIVE;
157			fldname = "home_drive";
158			break;
159
160		case comment:
161			continue_if_field_set(mod->in.change.comment);
162			mod->in.change.comment = talloc_asprintf(mem_ctx, TEST_CHG_COMMENT,
163								random(), random());
164			mod->in.change.fields |= USERMOD_FIELD_COMMENT;
165			fldname = "comment";
166			break;
167
168		case logon_script:
169			continue_if_field_set(mod->in.change.logon_script);
170			logonscript = logon_scripts[random() % (sizeof(logon_scripts)/sizeof(char*))];
171			mod->in.change.logon_script = talloc_strdup(mem_ctx, logonscript);
172			mod->in.change.fields |= USERMOD_FIELD_LOGON_SCRIPT;
173			fldname = "logon_script";
174			break;
175
176		case profile_path:
177			continue_if_field_set(mod->in.change.profile_path);
178			mod->in.change.profile_path = talloc_asprintf(mem_ctx, TEST_CHG_PROFILEPATH,
179								     (long int)random(), (unsigned int)random());
180			mod->in.change.fields |= USERMOD_FIELD_PROFILE_PATH;
181			fldname = "profile_path";
182			break;
183
184		case acct_expiry:
185			continue_if_field_set(mod->in.change.acct_expiry);
186			now = timeval_add(&now, (random() % (31*24*60*60)), 0);
187			mod->in.change.acct_expiry = (struct timeval *)talloc_memdup(mem_ctx, &now, sizeof(now));
188			mod->in.change.fields |= USERMOD_FIELD_ACCT_EXPIRY;
189			fldname = "acct_expiry";
190			break;
191
192		case acct_flags:
193			continue_if_field_set(mod->in.change.acct_flags);
194			mod->in.change.acct_flags = flags[random() % ARRAY_SIZE(flags)];
195			mod->in.change.fields |= USERMOD_FIELD_ACCT_FLAGS;
196			fldname = "acct_flags";
197			break;
198
199		default:
200			fldname = talloc_asprintf(mem_ctx, "unknown_field (%d)", testfld);
201			break;
202		}
203
204		torture_comment(tctx, ((i < num_changes - 1) ? "%s," : "%s"), fldname);
205	}
206	torture_comment(tctx, "]\n");
207
208	status = libnet_rpc_usermod(p, mem_ctx, mod);
209	torture_assert_ntstatus_ok(tctx, status, "Failed to call sync libnet_rpc_usermod");
210
211	return true;
212}
213
214
215static bool test_userdel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
216			 struct policy_handle *handle, const char *username)
217{
218	NTSTATUS status;
219	struct libnet_rpc_userdel user;
220
221	user.in.domain_handle = *handle;
222	user.in.username = username;
223
224	status = libnet_rpc_userdel(p, mem_ctx, &user);
225	if (!NT_STATUS_IS_OK(status)) {
226		printf("Failed to call sync libnet_rpc_userdel - %s\n", nt_errstr(status));
227		return false;
228	}
229
230	return true;
231}
232
233
234#define CMP_LSA_STRING_FLD(fld, flags) \
235	if ((mod->in.change.fields & flags) && \
236	    !strequal(i->fld.string, mod->in.change.fld)) { \
237		printf("'%s' field does not match\n", #fld); \
238		printf("received: '%s'\n", i->fld.string); \
239		printf("expected: '%s'\n", mod->in.change.fld); \
240		return false; \
241	}
242
243
244#define CMP_TIME_FLD(fld, flags) \
245	if (mod->in.change.fields & flags) { \
246		nttime_to_timeval(&t, i->fld); \
247		if (timeval_compare(&t, mod->in.change.fld)) { \
248			printf("'%s' field does not match\n", #fld); \
249			printf("received: '%s (+%ld us)'\n", \
250			       timestring(mem_ctx, t.tv_sec), t.tv_usec); \
251			printf("expected: '%s (+%ld us)'\n", \
252			       timestring(mem_ctx, mod->in.change.fld->tv_sec), \
253			       mod->in.change.fld->tv_usec); \
254			return false; \
255		} \
256	}
257
258#define CMP_NUM_FLD(fld, flags) \
259	if ((mod->in.change.fields & flags) && \
260	    (i->fld != mod->in.change.fld)) { \
261		printf("'%s' field does not match\n", #fld); \
262		printf("received: '%04x'\n", i->fld); \
263		printf("expected: '%04x'\n", mod->in.change.fld); \
264		return false; \
265	}
266
267
268static bool test_compare(struct torture_context *tctx,
269			 struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
270			 struct policy_handle *handle, struct libnet_rpc_usermod *mod,
271			 const char *username)
272{
273	NTSTATUS status;
274	struct libnet_rpc_userinfo info;
275	struct samr_UserInfo21 *i;
276	struct timeval t;
277
278	ZERO_STRUCT(info);
279
280	info.in.username = username;
281	info.in.domain_handle = *handle;
282	info.in.level = 21;             /* the most rich infolevel available */
283
284	status = libnet_rpc_userinfo(p, mem_ctx, &info);
285	torture_assert_ntstatus_ok(tctx, status, "Failed to call sync libnet_rpc_userinfo");
286
287	i = &info.out.info.info21;
288
289	CMP_LSA_STRING_FLD(account_name, USERMOD_FIELD_ACCOUNT_NAME);
290	CMP_LSA_STRING_FLD(full_name, USERMOD_FIELD_FULL_NAME);
291	CMP_LSA_STRING_FLD(description, USERMOD_FIELD_DESCRIPTION);
292	CMP_LSA_STRING_FLD(comment, USERMOD_FIELD_COMMENT);
293	CMP_LSA_STRING_FLD(logon_script, USERMOD_FIELD_LOGON_SCRIPT);
294	CMP_LSA_STRING_FLD(profile_path, USERMOD_FIELD_PROFILE_PATH);
295	CMP_LSA_STRING_FLD(home_directory, USERMOD_FIELD_HOME_DIRECTORY);
296	CMP_LSA_STRING_FLD(home_drive, USERMOD_FIELD_HOME_DRIVE);
297	CMP_TIME_FLD(acct_expiry, USERMOD_FIELD_ACCT_EXPIRY);
298	CMP_NUM_FLD(acct_flags, USERMOD_FIELD_ACCT_FLAGS)
299
300	return true;
301}
302
303
304bool torture_useradd(struct torture_context *torture)
305{
306	NTSTATUS status;
307	struct dcerpc_pipe *p;
308	struct policy_handle h;
309	struct lsa_String domain_name;
310	struct dom_sid2 sid;
311	const char *name = TEST_USERNAME;
312	TALLOC_CTX *mem_ctx;
313	bool ret = true;
314
315	mem_ctx = talloc_init("test_useradd");
316
317	status = torture_rpc_connection(torture,
318					&p,
319					&ndr_table_samr);
320
321	torture_assert_ntstatus_ok(torture, status, "RPC connect failed");
322
323	domain_name.string = lp_workgroup(torture->lp_ctx);
324	if (!test_opendomain(torture, p, mem_ctx, &h, &domain_name, &sid)) {
325		ret = false;
326		goto done;
327	}
328
329	if (!test_useradd(p, mem_ctx, &h, name)) {
330		ret = false;
331		goto done;
332	}
333
334	if (!test_user_cleanup(torture, p, mem_ctx, &h, name)) {
335		ret = false;
336		goto done;
337	}
338
339	if (!test_opendomain(torture, p, mem_ctx, &h, &domain_name, &sid)) {
340		ret = false;
341		goto done;
342	}
343
344	if (!test_useradd_async(p, mem_ctx, &h, name)) {
345		ret = false;
346		goto done;
347	}
348
349	if (!test_user_cleanup(torture, p, mem_ctx, &h, name)) {
350		ret = false;
351		goto done;
352	}
353
354done:
355	talloc_free(mem_ctx);
356	return ret;
357}
358
359
360bool torture_userdel(struct torture_context *torture)
361{
362	NTSTATUS status;
363	struct dcerpc_pipe *p;
364	struct policy_handle h;
365	struct lsa_String domain_name;
366	struct dom_sid2 sid;
367	uint32_t rid;
368	const char *name = TEST_USERNAME;
369	TALLOC_CTX *mem_ctx;
370	bool ret = true;
371
372	mem_ctx = talloc_init("test_userdel");
373
374	status = torture_rpc_connection(torture,
375					&p,
376					&ndr_table_samr);
377
378	if (!NT_STATUS_IS_OK(status)) {
379		return false;
380	}
381
382	domain_name.string = lp_workgroup(torture->lp_ctx);
383	if (!test_opendomain(torture, p, mem_ctx, &h, &domain_name, &sid)) {
384		ret = false;
385		goto done;
386	}
387
388	if (!test_user_create(torture, p, mem_ctx, &h, name, &rid)) {
389		ret = false;
390		goto done;
391	}
392
393       	if (!test_userdel(p, mem_ctx, &h, name)) {
394		ret = false;
395		goto done;
396	}
397
398done:
399	talloc_free(mem_ctx);
400	return ret;
401}
402
403
404bool torture_usermod(struct torture_context *torture)
405{
406	NTSTATUS status;
407	struct dcerpc_pipe *p;
408	struct policy_handle h;
409	struct lsa_String domain_name;
410	struct dom_sid2 sid;
411	uint32_t rid;
412	int i;
413	char *name;
414	TALLOC_CTX *mem_ctx;
415	bool ret = true;
416
417	mem_ctx = talloc_init("test_userdel");
418
419	status = torture_rpc_connection(torture,
420					&p,
421					&ndr_table_samr);
422
423	torture_assert_ntstatus_ok(torture, status, "RPC connect");
424
425	domain_name.string = lp_workgroup(torture->lp_ctx);
426	name = talloc_strdup(mem_ctx, TEST_USERNAME);
427
428	if (!test_opendomain(torture, p, mem_ctx, &h, &domain_name, &sid)) {
429		ret = false;
430		goto done;
431	}
432
433	if (!test_user_create(torture, p, mem_ctx, &h, name, &rid)) {
434		ret = false;
435		goto done;
436	}
437
438	for (i = 1; i < FIELDS_NUM; i++) {
439		struct libnet_rpc_usermod m;
440
441		if (!test_usermod(torture, p, mem_ctx, &h, i, &m, &name)) {
442			ret = false;
443			goto cleanup;
444		}
445
446		if (!test_compare(torture, p, mem_ctx, &h, &m, name)) {
447			ret = false;
448			goto cleanup;
449		}
450	}
451
452cleanup:
453	if (!test_user_cleanup(torture, p, mem_ctx, &h, name)) {
454		ret = false;
455		goto done;
456	}
457
458done:
459	talloc_free(mem_ctx);
460	return ret;
461}
462