• 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/smb2/
1/*
2   Unix SMB/CIFS implementation.
3
4   test suite for SMB2 compounded requests
5
6   Copyright (C) Stefan Metzmacher 2009
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "librpc/gen_ndr/security.h"
24#include "libcli/smb2/smb2.h"
25#include "libcli/smb2/smb2_calls.h"
26#include "torture/torture.h"
27#include "torture/smb2/proto.h"
28
29#define CHECK_STATUS(status, correct) do { \
30	if (!NT_STATUS_EQUAL(status, correct)) { \
31		torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
32		       nt_errstr(status), nt_errstr(correct)); \
33		ret = false; \
34		goto done; \
35	}} while (0)
36
37static bool test_compound_related1(struct torture_context *tctx,
38				   struct smb2_tree *tree)
39{
40	struct smb2_handle hd;
41	struct smb2_create cr;
42	NTSTATUS status;
43	const char *fname = "compound_related1.dat";
44	struct smb2_close cl;
45	bool ret = true;
46	struct smb2_request *req[2];
47	DATA_BLOB data;
48
49	smb2_transport_credits_ask_num(tree->session->transport, 2);
50
51	smb2_util_unlink(tree, fname);
52
53	smb2_transport_credits_ask_num(tree->session->transport, 1);
54
55	ZERO_STRUCT(cr);
56	cr.in.security_flags		= 0x00;
57	cr.in.oplock_level		= 0;
58	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
59	cr.in.create_flags		= 0x00000000;
60	cr.in.reserved			= 0x00000000;
61	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
62	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
63	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
64					  NTCREATEX_SHARE_ACCESS_WRITE |
65					  NTCREATEX_SHARE_ACCESS_DELETE;
66	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
67	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
68					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
69					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
70					  0x00200000;
71	cr.in.fname			= fname;
72
73	smb2_transport_compound_start(tree->session->transport, 2);
74
75	req[0] = smb2_create_send(tree, &cr);
76
77	smb2_transport_compound_set_related(tree->session->transport, true);
78
79	hd.data[0] = UINT64_MAX;
80	hd.data[1] = UINT64_MAX;
81
82	ZERO_STRUCT(cl);
83	cl.in.file.handle = hd;
84	req[1] = smb2_close_send(tree, &cl);
85
86	status = smb2_create_recv(req[0], tree, &cr);
87	CHECK_STATUS(status, NT_STATUS_OK);
88	status = smb2_close_recv(req[1], &cl);
89	CHECK_STATUS(status, NT_STATUS_OK);
90
91	smb2_util_unlink(tree, fname);
92done:
93	return ret;
94}
95
96static bool test_compound_related2(struct torture_context *tctx,
97				   struct smb2_tree *tree)
98{
99	struct smb2_handle hd;
100	struct smb2_create cr;
101	NTSTATUS status;
102	const char *fname = "compound_related2.dat";
103	struct smb2_close cl;
104	bool ret = true;
105	struct smb2_request *req[5];
106
107	smb2_transport_credits_ask_num(tree->session->transport, 5);
108
109	smb2_util_unlink(tree, fname);
110
111	smb2_transport_credits_ask_num(tree->session->transport, 1);
112
113	ZERO_STRUCT(cr);
114	cr.in.security_flags		= 0x00;
115	cr.in.oplock_level		= 0;
116	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
117	cr.in.create_flags		= 0x00000000;
118	cr.in.reserved			= 0x00000000;
119	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
120	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
121	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
122					  NTCREATEX_SHARE_ACCESS_WRITE |
123					  NTCREATEX_SHARE_ACCESS_DELETE;
124	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
125	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
126					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
127					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
128					  0x00200000;
129	cr.in.fname			= fname;
130
131	smb2_transport_compound_start(tree->session->transport, 5);
132
133	req[0] = smb2_create_send(tree, &cr);
134
135	hd.data[0] = UINT64_MAX;
136	hd.data[1] = UINT64_MAX;
137
138	smb2_transport_compound_set_related(tree->session->transport, true);
139
140	ZERO_STRUCT(cl);
141	cl.in.file.handle = hd;
142	req[1] = smb2_close_send(tree, &cl);
143	req[2] = smb2_close_send(tree, &cl);
144	req[3] = smb2_close_send(tree, &cl);
145	req[4] = smb2_close_send(tree, &cl);
146
147	status = smb2_create_recv(req[0], tree, &cr);
148	CHECK_STATUS(status, NT_STATUS_OK);
149	status = smb2_close_recv(req[1], &cl);
150	CHECK_STATUS(status, NT_STATUS_OK);
151	status = smb2_close_recv(req[2], &cl);
152	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
153	status = smb2_close_recv(req[3], &cl);
154	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
155	status = smb2_close_recv(req[4], &cl);
156	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
157
158	smb2_util_unlink(tree, fname);
159done:
160	return ret;
161}
162
163static bool test_compound_unrelated1(struct torture_context *tctx,
164				     struct smb2_tree *tree)
165{
166	struct smb2_handle hd;
167	struct smb2_create cr;
168	NTSTATUS status;
169	const char *fname = "compound_unrelated1.dat";
170	struct smb2_close cl;
171	bool ret = true;
172	struct smb2_request *req[5];
173	uint64_t uid;
174	uint32_t tid;
175
176	smb2_transport_credits_ask_num(tree->session->transport, 5);
177
178	smb2_util_unlink(tree, fname);
179
180	smb2_transport_credits_ask_num(tree->session->transport, 1);
181
182	ZERO_STRUCT(cr);
183	cr.in.security_flags		= 0x00;
184	cr.in.oplock_level		= 0;
185	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
186	cr.in.create_flags		= 0x00000000;
187	cr.in.reserved			= 0x00000000;
188	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
189	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
190	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
191					  NTCREATEX_SHARE_ACCESS_WRITE |
192					  NTCREATEX_SHARE_ACCESS_DELETE;
193	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
194	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
195					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
196					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
197					  0x00200000;
198	cr.in.fname			= fname;
199
200	smb2_transport_compound_start(tree->session->transport, 5);
201
202	req[0] = smb2_create_send(tree, &cr);
203
204	hd.data[0] = UINT64_MAX;
205	hd.data[1] = UINT64_MAX;
206
207	ZERO_STRUCT(cl);
208	cl.in.file.handle = hd;
209	req[1] = smb2_close_send(tree, &cl);
210	req[2] = smb2_close_send(tree, &cl);
211	req[3] = smb2_close_send(tree, &cl);
212	req[4] = smb2_close_send(tree, &cl);
213
214	status = smb2_create_recv(req[0], tree, &cr);
215	CHECK_STATUS(status, NT_STATUS_OK);
216	status = smb2_close_recv(req[1], &cl);
217	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
218	status = smb2_close_recv(req[2], &cl);
219	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
220	status = smb2_close_recv(req[3], &cl);
221	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
222	status = smb2_close_recv(req[4], &cl);
223	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
224
225	smb2_util_unlink(tree, fname);
226done:
227	return ret;
228}
229
230static bool test_compound_invalid1(struct torture_context *tctx,
231				   struct smb2_tree *tree)
232{
233	struct smb2_handle hd;
234	struct smb2_create cr;
235	NTSTATUS status;
236	const char *fname = "compound_invalid1.dat";
237	struct smb2_close cl;
238	bool ret = true;
239	struct smb2_request *req[2];
240	DATA_BLOB data;
241
242	smb2_transport_credits_ask_num(tree->session->transport, 2);
243
244	smb2_util_unlink(tree, fname);
245
246	smb2_transport_credits_ask_num(tree->session->transport, 1);
247
248	ZERO_STRUCT(cr);
249	cr.in.security_flags		= 0x00;
250	cr.in.oplock_level		= 0;
251	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
252	cr.in.create_flags		= 0x00000000;
253	cr.in.reserved			= 0x00000000;
254	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
255	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
256	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
257					  NTCREATEX_SHARE_ACCESS_WRITE |
258					  NTCREATEX_SHARE_ACCESS_DELETE;
259	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
260	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
261					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
262					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
263					  0x00200000;
264	cr.in.fname			= fname;
265
266	smb2_transport_compound_start(tree->session->transport, 2);
267
268	/* passing the first request with the related flag is invalid */
269	smb2_transport_compound_set_related(tree->session->transport, true);
270
271	req[0] = smb2_create_send(tree, &cr);
272
273	hd.data[0] = UINT64_MAX;
274	hd.data[1] = UINT64_MAX;
275
276	ZERO_STRUCT(cl);
277	cl.in.file.handle = hd;
278	req[1] = smb2_close_send(tree, &cl);
279
280	status = smb2_create_recv(req[0], tree, &cr);
281	/* TODO: check why this fails with --signing=required */
282	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
283	status = smb2_close_recv(req[1], &cl);
284	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
285
286	smb2_util_unlink(tree, fname);
287done:
288	return ret;
289}
290
291static bool test_compound_invalid2(struct torture_context *tctx,
292				   struct smb2_tree *tree)
293{
294	struct smb2_handle hd;
295	struct smb2_create cr;
296	NTSTATUS status;
297	const char *fname = "compound_invalid2.dat";
298	struct smb2_close cl;
299	bool ret = true;
300	struct smb2_request *req[5];
301
302	smb2_transport_credits_ask_num(tree->session->transport, 5);
303
304	smb2_util_unlink(tree, fname);
305
306	smb2_transport_credits_ask_num(tree->session->transport, 1);
307
308	ZERO_STRUCT(cr);
309	cr.in.security_flags		= 0x00;
310	cr.in.oplock_level		= 0;
311	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
312	cr.in.create_flags		= 0x00000000;
313	cr.in.reserved			= 0x00000000;
314	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
315	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
316	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
317					  NTCREATEX_SHARE_ACCESS_WRITE |
318					  NTCREATEX_SHARE_ACCESS_DELETE;
319	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
320	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
321					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
322					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
323					  0x00200000;
324	cr.in.fname			= fname;
325
326	smb2_transport_compound_start(tree->session->transport, 5);
327
328	req[0] = smb2_create_send(tree, &cr);
329
330	hd.data[0] = UINT64_MAX;
331	hd.data[1] = UINT64_MAX;
332
333	smb2_transport_compound_set_related(tree->session->transport, true);
334
335	ZERO_STRUCT(cl);
336	cl.in.file.handle = hd;
337	req[1] = smb2_close_send(tree, &cl);
338	/* strange that this is not generating invalid parameter */
339	smb2_transport_compound_set_related(tree->session->transport, false);
340	req[2] = smb2_close_send(tree, &cl);
341	req[3] = smb2_close_send(tree, &cl);
342	smb2_transport_compound_set_related(tree->session->transport, true);
343	req[4] = smb2_close_send(tree, &cl);
344
345	status = smb2_create_recv(req[0], tree, &cr);
346	CHECK_STATUS(status, NT_STATUS_OK);
347	status = smb2_close_recv(req[1], &cl);
348	CHECK_STATUS(status, NT_STATUS_OK);
349	status = smb2_close_recv(req[2], &cl);
350	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
351	status = smb2_close_recv(req[3], &cl);
352	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
353	status = smb2_close_recv(req[4], &cl);
354	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
355
356	smb2_util_unlink(tree, fname);
357done:
358	return ret;
359}
360
361static bool test_compound_invalid3(struct torture_context *tctx,
362				   struct smb2_tree *tree)
363{
364	struct smb2_handle hd;
365	struct smb2_create cr;
366	NTSTATUS status;
367	const char *fname = "compound_invalid3.dat";
368	struct smb2_close cl;
369	bool ret = true;
370	struct smb2_request *req[5];
371
372	smb2_transport_credits_ask_num(tree->session->transport, 5);
373
374	smb2_util_unlink(tree, fname);
375
376	smb2_transport_credits_ask_num(tree->session->transport, 1);
377
378	ZERO_STRUCT(cr);
379	cr.in.security_flags		= 0x00;
380	cr.in.oplock_level		= 0;
381	cr.in.impersonation_level	= NTCREATEX_IMPERSONATION_IMPERSONATION;
382	cr.in.create_flags		= 0x00000000;
383	cr.in.reserved			= 0x00000000;
384	cr.in.desired_access		= SEC_RIGHTS_FILE_ALL;
385	cr.in.file_attributes		= FILE_ATTRIBUTE_NORMAL;
386	cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
387					  NTCREATEX_SHARE_ACCESS_WRITE |
388					  NTCREATEX_SHARE_ACCESS_DELETE;
389	cr.in.create_disposition	= NTCREATEX_DISP_OPEN_IF;
390	cr.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
391					  NTCREATEX_OPTIONS_ASYNC_ALERT	|
392					  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
393					  0x00200000;
394	cr.in.fname			= fname;
395
396	smb2_transport_compound_start(tree->session->transport, 5);
397
398	req[0] = smb2_create_send(tree, &cr);
399
400	hd.data[0] = UINT64_MAX;
401	hd.data[1] = UINT64_MAX;
402
403	ZERO_STRUCT(cl);
404	cl.in.file.handle = hd;
405	req[1] = smb2_close_send(tree, &cl);
406	req[2] = smb2_close_send(tree, &cl);
407	/* flipping the related flag is invalid */
408	smb2_transport_compound_set_related(tree->session->transport, true);
409	req[3] = smb2_close_send(tree, &cl);
410	req[4] = smb2_close_send(tree, &cl);
411
412	status = smb2_create_recv(req[0], tree, &cr);
413	CHECK_STATUS(status, NT_STATUS_OK);
414	status = smb2_close_recv(req[1], &cl);
415	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
416	status = smb2_close_recv(req[2], &cl);
417	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
418	status = smb2_close_recv(req[3], &cl);
419	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
420	status = smb2_close_recv(req[4], &cl);
421	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
422
423	smb2_util_unlink(tree, fname);
424done:
425	return ret;
426}
427
428struct torture_suite *torture_smb2_compound_init(void)
429{
430	struct torture_suite *suite =
431	    torture_suite_create(talloc_autofree_context(), "COMPOUND");
432
433	torture_suite_add_1smb2_test(suite, "RELATED1", test_compound_related1);
434	torture_suite_add_1smb2_test(suite, "RELATED2", test_compound_related2);
435	torture_suite_add_1smb2_test(suite, "UNRELATED1", test_compound_unrelated1);
436	torture_suite_add_1smb2_test(suite, "INVALID1", test_compound_invalid1);
437	torture_suite_add_1smb2_test(suite, "INVALID2", test_compound_invalid2);
438	torture_suite_add_1smb2_test(suite, "INVALID3", test_compound_invalid3);
439
440	suite->description = talloc_strdup(suite, "SMB2-COMPOUND tests");
441
442	return suite;
443}
444