source: trunk/server/source4/torture/raw/context.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 29.7 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 test suite for session setup operations
4 Copyright (C) Andrew Tridgell 2003
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "includes.h"
21#include "libcli/raw/libcliraw.h"
22#include "libcli/raw/raw_proto.h"
23#include "libcli/smb_composite/smb_composite.h"
24#include "lib/cmdline/popt_common.h"
25#include "libcli/libcli.h"
26#include "torture/util.h"
27#include "auth/credentials/credentials.h"
28#include "param/param.h"
29
30#define BASEDIR "\\rawcontext"
31
32#define CHECK_STATUS(status, correct) do { \
33 if (!NT_STATUS_EQUAL(status, correct)) { \
34 printf("(%s) Incorrect status %s - should be %s\n", \
35 __location__, nt_errstr(status), nt_errstr(correct)); \
36 ret = false; \
37 goto done; \
38 }} while (0)
39
40#define CHECK_VALUE(v, correct) do { \
41 if ((v) != (correct)) { \
42 printf("(%s) Incorrect value %s=%d - should be %d\n", \
43 __location__, #v, v, correct); \
44 ret = false; \
45 goto done; \
46 }} while (0)
47
48#define CHECK_NOT_VALUE(v, correct) do { \
49 if ((v) == (correct)) { \
50 printf("(%s) Incorrect value %s=%d - should not be %d\n", \
51 __location__, #v, v, correct); \
52 ret = false; \
53 goto done; \
54 }} while (0)
55
56
57/*
58 test session ops
59*/
60static bool test_session(struct smbcli_state *cli, struct torture_context *tctx)
61{
62 NTSTATUS status;
63 bool ret = true;
64 struct smbcli_session *session;
65 struct smbcli_session *session2;
66 struct smbcli_session *session3;
67 struct smbcli_session *session4;
68 struct cli_credentials *anon_creds;
69 struct smbcli_session *sessions[15];
70 struct composite_context *composite_contexts[15];
71 struct smbcli_tree *tree;
72 struct smb_composite_sesssetup setup;
73 struct smb_composite_sesssetup setups[15];
74 struct gensec_settings *gensec_settings;
75 union smb_open io;
76 union smb_write wr;
77 union smb_close cl;
78 int fnum;
79 const char *fname = BASEDIR "\\test.txt";
80 uint8_t c = 1;
81 int i;
82 struct smbcli_session_options options;
83
84 printf("TESTING SESSION HANDLING\n");
85
86 if (!torture_setup_dir(cli, BASEDIR)) {
87 return false;
88 }
89
90 printf("create a second security context on the same transport\n");
91
92 lpcfg_smbcli_session_options(tctx->lp_ctx, &options);
93 gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
94
95 session = smbcli_session_init(cli->transport, tctx, false, options);
96
97 setup.in.sesskey = cli->transport->negotiate.sesskey;
98 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
99 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
100
101 setup.in.credentials = cmdline_credentials;
102 setup.in.gensec_settings = gensec_settings;
103
104 status = smb_composite_sesssetup(session, &setup);
105 CHECK_STATUS(status, NT_STATUS_OK);
106
107 session->vuid = setup.out.vuid;
108
109 printf("create a third security context on the same transport, with vuid set\n");
110 session2 = smbcli_session_init(cli->transport, tctx, false, options);
111
112 session2->vuid = session->vuid;
113 setup.in.sesskey = cli->transport->negotiate.sesskey;
114 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
115 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
116
117 setup.in.credentials = cmdline_credentials;
118
119 status = smb_composite_sesssetup(session2, &setup);
120 CHECK_STATUS(status, NT_STATUS_OK);
121
122 session2->vuid = setup.out.vuid;
123 printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
124
125 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
126 /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
127 if (session2->vuid == session->vuid) {
128 printf("server allows the user to re-use an existing vuid in session setup \n");
129 }
130 } else {
131 CHECK_NOT_VALUE(session2->vuid, session->vuid);
132 }
133 talloc_free(session2);
134
135 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
136 printf("create a fourth security context on the same transport, without extended security\n");
137 session3 = smbcli_session_init(cli->transport, tctx, false, options);
138
139 session3->vuid = session->vuid;
140 setup.in.sesskey = cli->transport->negotiate.sesskey;
141 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
142 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
143
144 setup.in.credentials = cmdline_credentials;
145
146 status = smb_composite_sesssetup(session3, &setup);
147 CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
148
149 printf("create a fouth anonymous security context on the same transport, without extended security\n");
150 session4 = smbcli_session_init(cli->transport, tctx, false, options);
151
152 session4->vuid = session->vuid;
153 setup.in.sesskey = cli->transport->negotiate.sesskey;
154 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
155 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
156
157 anon_creds = cli_credentials_init(tctx);
158 cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
159 cli_credentials_set_anonymous(anon_creds);
160
161 setup.in.credentials = anon_creds;
162
163 status = smb_composite_sesssetup(session3, &setup);
164 CHECK_STATUS(status, NT_STATUS_OK);
165
166 talloc_free(session4);
167 }
168
169 printf("use the same tree as the existing connection\n");
170 tree = smbcli_tree_init(session, tctx, false);
171 tree->tid = cli->tree->tid;
172
173 printf("create a file using the new vuid\n");
174 io.generic.level = RAW_OPEN_NTCREATEX;
175 io.ntcreatex.in.root_fid.fnum = 0;
176 io.ntcreatex.in.flags = 0;
177 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
178 io.ntcreatex.in.create_options = 0;
179 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
180 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
181 io.ntcreatex.in.alloc_size = 0;
182 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
183 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
184 io.ntcreatex.in.security_flags = 0;
185 io.ntcreatex.in.fname = fname;
186 status = smb_raw_open(tree, tctx, &io);
187 CHECK_STATUS(status, NT_STATUS_OK);
188 fnum = io.ntcreatex.out.file.fnum;
189
190 printf("write using the old vuid\n");
191 wr.generic.level = RAW_WRITE_WRITEX;
192 wr.writex.in.file.fnum = fnum;
193 wr.writex.in.offset = 0;
194 wr.writex.in.wmode = 0;
195 wr.writex.in.remaining = 0;
196 wr.writex.in.count = 1;
197 wr.writex.in.data = &c;
198
199 status = smb_raw_write(cli->tree, &wr);
200 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
201
202 printf("write with the new vuid\n");
203 status = smb_raw_write(tree, &wr);
204 CHECK_STATUS(status, NT_STATUS_OK);
205 CHECK_VALUE(wr.writex.out.nwritten, 1);
206
207 printf("logoff the new vuid\n");
208 status = smb_raw_ulogoff(session);
209 CHECK_STATUS(status, NT_STATUS_OK);
210
211 printf("the new vuid should not now be accessible\n");
212 status = smb_raw_write(tree, &wr);
213 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
214
215 printf("second logoff for the new vuid should fail\n");
216 status = smb_raw_ulogoff(session);
217 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
218 talloc_free(session);
219
220 printf("the fnum should have been auto-closed\n");
221 cl.close.level = RAW_CLOSE_CLOSE;
222 cl.close.in.file.fnum = fnum;
223 cl.close.in.write_time = 0;
224 status = smb_raw_close(cli->tree, &cl);
225 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
226
227 printf("create %d secondary security contexts on the same transport\n",
228 (int)ARRAY_SIZE(sessions));
229 for (i=0; i <ARRAY_SIZE(sessions); i++) {
230 setups[i].in.sesskey = cli->transport->negotiate.sesskey;
231 setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
232 setups[i].in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
233
234 setups[i].in.credentials = cmdline_credentials;
235 setups[i].in.gensec_settings = gensec_settings;
236
237 sessions[i] = smbcli_session_init(cli->transport, tctx, false, options);
238 composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
239
240 }
241
242
243 printf("finishing %d secondary security contexts on the same transport\n",
244 (int)ARRAY_SIZE(sessions));
245 for (i=0; i< ARRAY_SIZE(sessions); i++) {
246 status = smb_composite_sesssetup_recv(composite_contexts[i]);
247 CHECK_STATUS(status, NT_STATUS_OK);
248 sessions[i]->vuid = setups[i].out.vuid;
249 printf("VUID: %d\n", sessions[i]->vuid);
250 status = smb_raw_ulogoff(sessions[i]);
251 CHECK_STATUS(status, NT_STATUS_OK);
252 }
253
254
255 talloc_free(tree);
256
257done:
258 return ret;
259}
260
261
262/*
263 test tree ops
264*/
265static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
266{
267 NTSTATUS status;
268 bool ret = true;
269 const char *share, *host;
270 struct smbcli_tree *tree;
271 union smb_tcon tcon;
272 union smb_open io;
273 union smb_write wr;
274 union smb_close cl;
275 int fnum;
276 const char *fname = BASEDIR "\\test.txt";
277 uint8_t c = 1;
278
279 printf("TESTING TREE HANDLING\n");
280
281 if (!torture_setup_dir(cli, BASEDIR)) {
282 return false;
283 }
284
285 share = torture_setting_string(tctx, "share", NULL);
286 host = torture_setting_string(tctx, "host", NULL);
287
288 printf("create a second tree context on the same session\n");
289 tree = smbcli_tree_init(cli->session, tctx, false);
290
291 tcon.generic.level = RAW_TCON_TCONX;
292 tcon.tconx.in.flags = 0;
293 tcon.tconx.in.password = data_blob(NULL, 0);
294 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
295 tcon.tconx.in.device = "A:";
296 status = smb_raw_tcon(tree, tctx, &tcon);
297 CHECK_STATUS(status, NT_STATUS_OK);
298
299
300 tree->tid = tcon.tconx.out.tid;
301 printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
302
303 printf("try a tconx with a bad device type\n");
304 tcon.tconx.in.device = "FOO";
305 status = smb_raw_tcon(tree, tctx, &tcon);
306 CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
307
308
309 printf("create a file using the new tid\n");
310 io.generic.level = RAW_OPEN_NTCREATEX;
311 io.ntcreatex.in.root_fid.fnum = 0;
312 io.ntcreatex.in.flags = 0;
313 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
314 io.ntcreatex.in.create_options = 0;
315 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
316 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
317 io.ntcreatex.in.alloc_size = 0;
318 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
319 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
320 io.ntcreatex.in.security_flags = 0;
321 io.ntcreatex.in.fname = fname;
322 status = smb_raw_open(tree, tctx, &io);
323 CHECK_STATUS(status, NT_STATUS_OK);
324 fnum = io.ntcreatex.out.file.fnum;
325
326 printf("write using the old tid\n");
327 wr.generic.level = RAW_WRITE_WRITEX;
328 wr.writex.in.file.fnum = fnum;
329 wr.writex.in.offset = 0;
330 wr.writex.in.wmode = 0;
331 wr.writex.in.remaining = 0;
332 wr.writex.in.count = 1;
333 wr.writex.in.data = &c;
334
335 status = smb_raw_write(cli->tree, &wr);
336 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
337
338 printf("write with the new tid\n");
339 status = smb_raw_write(tree, &wr);
340 CHECK_STATUS(status, NT_STATUS_OK);
341 CHECK_VALUE(wr.writex.out.nwritten, 1);
342
343 printf("disconnect the new tid\n");
344 status = smb_tree_disconnect(tree);
345 CHECK_STATUS(status, NT_STATUS_OK);
346
347 printf("the new tid should not now be accessible\n");
348 status = smb_raw_write(tree, &wr);
349 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
350
351 printf("the fnum should have been auto-closed\n");
352 cl.close.level = RAW_CLOSE_CLOSE;
353 cl.close.in.file.fnum = fnum;
354 cl.close.in.write_time = 0;
355 status = smb_raw_close(cli->tree, &cl);
356 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
357
358 /* close down the new tree */
359 talloc_free(tree);
360
361done:
362 return ret;
363}
364
365/*
366 test tree with ulogoff
367 this demonstrates that a tcon isn't autoclosed by a ulogoff
368 the tcon can be reused using any other valid session later
369*/
370static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
371{
372 NTSTATUS status;
373 bool ret = true;
374 const char *share, *host;
375 struct smbcli_session *session1;
376 struct smbcli_session *session2;
377 struct smb_composite_sesssetup setup;
378 struct smbcli_tree *tree;
379 union smb_tcon tcon;
380 union smb_open io;
381 union smb_write wr;
382 int fnum1, fnum2;
383 const char *fname1 = BASEDIR "\\test1.txt";
384 const char *fname2 = BASEDIR "\\test2.txt";
385 uint8_t c = 1;
386 struct smbcli_session_options options;
387
388 printf("TESTING TREE with ulogoff\n");
389
390 if (!torture_setup_dir(cli, BASEDIR)) {
391 return false;
392 }
393
394 share = torture_setting_string(tctx, "share", NULL);
395 host = torture_setting_string(tctx, "host", NULL);
396
397 lpcfg_smbcli_session_options(tctx->lp_ctx, &options);
398
399 printf("create the first new sessions\n");
400 session1 = smbcli_session_init(cli->transport, tctx, false, options);
401 setup.in.sesskey = cli->transport->negotiate.sesskey;
402 setup.in.capabilities = cli->transport->negotiate.capabilities;
403 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
404 setup.in.credentials = cmdline_credentials;
405 setup.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
406 status = smb_composite_sesssetup(session1, &setup);
407 CHECK_STATUS(status, NT_STATUS_OK);
408 session1->vuid = setup.out.vuid;
409 printf("vuid1=%d\n", session1->vuid);
410
411 printf("create a tree context on the with vuid1\n");
412 tree = smbcli_tree_init(session1, tctx, false);
413 tcon.generic.level = RAW_TCON_TCONX;
414 tcon.tconx.in.flags = 0;
415 tcon.tconx.in.password = data_blob(NULL, 0);
416 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
417 tcon.tconx.in.device = "A:";
418 status = smb_raw_tcon(tree, tctx, &tcon);
419 CHECK_STATUS(status, NT_STATUS_OK);
420 tree->tid = tcon.tconx.out.tid;
421 printf("tid=%d\n", tree->tid);
422
423 printf("create a file using vuid1\n");
424 io.generic.level = RAW_OPEN_NTCREATEX;
425 io.ntcreatex.in.root_fid.fnum = 0;
426 io.ntcreatex.in.flags = 0;
427 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
428 io.ntcreatex.in.create_options = 0;
429 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
430 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
431 io.ntcreatex.in.alloc_size = 0;
432 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
433 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
434 io.ntcreatex.in.security_flags = 0;
435 io.ntcreatex.in.fname = fname1;
436 status = smb_raw_open(tree, tctx, &io);
437 CHECK_STATUS(status, NT_STATUS_OK);
438 fnum1 = io.ntcreatex.out.file.fnum;
439
440 printf("write using vuid1\n");
441 wr.generic.level = RAW_WRITE_WRITEX;
442 wr.writex.in.file.fnum = fnum1;
443 wr.writex.in.offset = 0;
444 wr.writex.in.wmode = 0;
445 wr.writex.in.remaining = 0;
446 wr.writex.in.count = 1;
447 wr.writex.in.data = &c;
448 status = smb_raw_write(tree, &wr);
449 CHECK_STATUS(status, NT_STATUS_OK);
450 CHECK_VALUE(wr.writex.out.nwritten, 1);
451
452 printf("ulogoff the vuid1\n");
453 status = smb_raw_ulogoff(session1);
454 CHECK_STATUS(status, NT_STATUS_OK);
455
456 printf("create the second new sessions\n");
457 session2 = smbcli_session_init(cli->transport, tctx, false, options);
458 setup.in.sesskey = cli->transport->negotiate.sesskey;
459 setup.in.capabilities = cli->transport->negotiate.capabilities;
460 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
461 setup.in.credentials = cmdline_credentials;
462 setup.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
463 status = smb_composite_sesssetup(session2, &setup);
464 CHECK_STATUS(status, NT_STATUS_OK);
465 session2->vuid = setup.out.vuid;
466 printf("vuid2=%d\n", session2->vuid);
467
468 printf("use the existing tree with vuid2\n");
469 tree->session = session2;
470
471 printf("create a file using vuid2\n");
472 io.generic.level = RAW_OPEN_NTCREATEX;
473 io.ntcreatex.in.root_fid.fnum = 0;
474 io.ntcreatex.in.flags = 0;
475 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
476 io.ntcreatex.in.create_options = 0;
477 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
478 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
479 io.ntcreatex.in.alloc_size = 0;
480 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
481 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
482 io.ntcreatex.in.security_flags = 0;
483 io.ntcreatex.in.fname = fname2;
484 status = smb_raw_open(tree, tctx, &io);
485 CHECK_STATUS(status, NT_STATUS_OK);
486 fnum2 = io.ntcreatex.out.file.fnum;
487
488 printf("write using vuid2\n");
489 wr.generic.level = RAW_WRITE_WRITEX;
490 wr.writex.in.file.fnum = fnum2;
491 wr.writex.in.offset = 0;
492 wr.writex.in.wmode = 0;
493 wr.writex.in.remaining = 0;
494 wr.writex.in.count = 1;
495 wr.writex.in.data = &c;
496 status = smb_raw_write(tree, &wr);
497 CHECK_STATUS(status, NT_STATUS_OK);
498 CHECK_VALUE(wr.writex.out.nwritten, 1);
499
500 printf("ulogoff the vuid2\n");
501 status = smb_raw_ulogoff(session2);
502 CHECK_STATUS(status, NT_STATUS_OK);
503
504 /* this also demonstrates that SMBtdis doesn't need a valid vuid */
505 printf("disconnect the existing tree connection\n");
506 status = smb_tree_disconnect(tree);
507 CHECK_STATUS(status, NT_STATUS_OK);
508
509 printf("disconnect the existing tree connection\n");
510 status = smb_tree_disconnect(tree);
511 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
512
513 /* close down the new tree */
514 talloc_free(tree);
515
516done:
517 return ret;
518}
519
520/*
521 test pid ops
522 this test demonstrates that exit() only sees the PID
523 used for the open() calls
524*/
525static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
526{
527 NTSTATUS status;
528 bool ret = true;
529 union smb_open io;
530 union smb_write wr;
531 union smb_close cl;
532 int fnum;
533 const char *fname = BASEDIR "\\test.txt";
534 uint8_t c = 1;
535 uint16_t pid1, pid2;
536
537 printf("TESTING PID HANDLING exit() only cares about open() PID\n");
538
539 if (!torture_setup_dir(cli, BASEDIR)) {
540 return false;
541 }
542
543 pid1 = cli->session->pid;
544 pid2 = pid1 + 1;
545
546 printf("pid1=%d pid2=%d\n", pid1, pid2);
547
548 printf("create a file using pid1\n");
549 cli->session->pid = pid1;
550 io.generic.level = RAW_OPEN_NTCREATEX;
551 io.ntcreatex.in.root_fid.fnum = 0;
552 io.ntcreatex.in.flags = 0;
553 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
554 io.ntcreatex.in.create_options = 0;
555 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
556 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
557 io.ntcreatex.in.alloc_size = 0;
558 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
559 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
560 io.ntcreatex.in.security_flags = 0;
561 io.ntcreatex.in.fname = fname;
562 status = smb_raw_open(cli->tree, mem_ctx, &io);
563 CHECK_STATUS(status, NT_STATUS_OK);
564 fnum = io.ntcreatex.out.file.fnum;
565
566 printf("write using pid2\n");
567 cli->session->pid = pid2;
568 wr.generic.level = RAW_WRITE_WRITEX;
569 wr.writex.in.file.fnum = fnum;
570 wr.writex.in.offset = 0;
571 wr.writex.in.wmode = 0;
572 wr.writex.in.remaining = 0;
573 wr.writex.in.count = 1;
574 wr.writex.in.data = &c;
575 status = smb_raw_write(cli->tree, &wr);
576 CHECK_STATUS(status, NT_STATUS_OK);
577 CHECK_VALUE(wr.writex.out.nwritten, 1);
578
579 printf("exit pid2\n");
580 cli->session->pid = pid2;
581 status = smb_raw_exit(cli->session);
582 CHECK_STATUS(status, NT_STATUS_OK);
583
584 printf("the fnum should still be accessible via pid2\n");
585 cli->session->pid = pid2;
586 status = smb_raw_write(cli->tree, &wr);
587 CHECK_STATUS(status, NT_STATUS_OK);
588 CHECK_VALUE(wr.writex.out.nwritten, 1);
589
590 printf("exit pid2\n");
591 cli->session->pid = pid2;
592 status = smb_raw_exit(cli->session);
593 CHECK_STATUS(status, NT_STATUS_OK);
594
595 printf("the fnum should still be accessible via pid1 and pid2\n");
596 cli->session->pid = pid1;
597 status = smb_raw_write(cli->tree, &wr);
598 CHECK_STATUS(status, NT_STATUS_OK);
599 CHECK_VALUE(wr.writex.out.nwritten, 1);
600 cli->session->pid = pid2;
601 status = smb_raw_write(cli->tree, &wr);
602 CHECK_STATUS(status, NT_STATUS_OK);
603 CHECK_VALUE(wr.writex.out.nwritten, 1);
604
605 printf("exit pid1\n");
606 cli->session->pid = pid1;
607 status = smb_raw_exit(cli->session);
608 CHECK_STATUS(status, NT_STATUS_OK);
609
610 printf("the fnum should not now be accessible via pid1 or pid2\n");
611 cli->session->pid = pid1;
612 status = smb_raw_write(cli->tree, &wr);
613 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
614 cli->session->pid = pid2;
615 status = smb_raw_write(cli->tree, &wr);
616 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
617
618 printf("the fnum should have been auto-closed\n");
619 cli->session->pid = pid1;
620 cl.close.level = RAW_CLOSE_CLOSE;
621 cl.close.in.file.fnum = fnum;
622 cl.close.in.write_time = 0;
623 status = smb_raw_close(cli->tree, &cl);
624 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
625
626done:
627 return ret;
628}
629
630/*
631 test pid ops with 2 sessions
632*/
633static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
634{
635 NTSTATUS status;
636 bool ret = true;
637 struct smbcli_session *session;
638 struct smb_composite_sesssetup setup;
639 union smb_open io;
640 union smb_write wr;
641 union smb_close cl;
642 int fnum;
643 const char *fname = BASEDIR "\\test.txt";
644 uint8_t c = 1;
645 uint16_t vuid1, vuid2;
646 struct smbcli_session_options options;
647
648 printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
649
650 if (!torture_setup_dir(cli, BASEDIR)) {
651 return false;
652 }
653
654 lpcfg_smbcli_session_options(tctx->lp_ctx, &options);
655
656 printf("create a second security context on the same transport\n");
657 session = smbcli_session_init(cli->transport, tctx, false, options);
658
659 setup.in.sesskey = cli->transport->negotiate.sesskey;
660 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
661 setup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
662 setup.in.credentials = cmdline_credentials;
663 setup.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
664
665 status = smb_composite_sesssetup(session, &setup);
666 CHECK_STATUS(status, NT_STATUS_OK);
667 session->vuid = setup.out.vuid;
668
669 vuid1 = cli->session->vuid;
670 vuid2 = session->vuid;
671
672 printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
673
674 printf("create a file using the vuid1\n");
675 cli->session->vuid = vuid1;
676 io.generic.level = RAW_OPEN_NTCREATEX;
677 io.ntcreatex.in.root_fid.fnum = 0;
678 io.ntcreatex.in.flags = 0;
679 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
680 io.ntcreatex.in.create_options = 0;
681 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
682 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
683 io.ntcreatex.in.alloc_size = 0;
684 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
685 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
686 io.ntcreatex.in.security_flags = 0;
687 io.ntcreatex.in.fname = fname;
688 status = smb_raw_open(cli->tree, tctx, &io);
689 CHECK_STATUS(status, NT_STATUS_OK);
690 fnum = io.ntcreatex.out.file.fnum;
691
692 printf("write using the vuid1 (fnum=%d)\n", fnum);
693 cli->session->vuid = vuid1;
694 wr.generic.level = RAW_WRITE_WRITEX;
695 wr.writex.in.file.fnum = fnum;
696 wr.writex.in.offset = 0;
697 wr.writex.in.wmode = 0;
698 wr.writex.in.remaining = 0;
699 wr.writex.in.count = 1;
700 wr.writex.in.data = &c;
701
702 status = smb_raw_write(cli->tree, &wr);
703 CHECK_STATUS(status, NT_STATUS_OK);
704 CHECK_VALUE(wr.writex.out.nwritten, 1);
705
706 printf("exit the pid with vuid2\n");
707 cli->session->vuid = vuid2;
708 status = smb_raw_exit(cli->session);
709 CHECK_STATUS(status, NT_STATUS_OK);
710
711 printf("the fnum should still be accessible\n");
712 cli->session->vuid = vuid1;
713 status = smb_raw_write(cli->tree, &wr);
714 CHECK_STATUS(status, NT_STATUS_OK);
715 CHECK_VALUE(wr.writex.out.nwritten, 1);
716
717 printf("exit the pid with vuid1\n");
718 cli->session->vuid = vuid1;
719 status = smb_raw_exit(cli->session);
720 CHECK_STATUS(status, NT_STATUS_OK);
721
722 printf("the fnum should not now be accessible\n");
723 status = smb_raw_write(cli->tree, &wr);
724 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
725
726 printf("the fnum should have been auto-closed\n");
727 cl.close.level = RAW_CLOSE_CLOSE;
728 cl.close.in.file.fnum = fnum;
729 cl.close.in.write_time = 0;
730 status = smb_raw_close(cli->tree, &cl);
731 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
732
733done:
734 return ret;
735}
736
737/*
738 test pid ops with 2 tcons
739*/
740static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
741{
742 NTSTATUS status;
743 bool ret = true;
744 const char *share, *host;
745 struct smbcli_tree *tree;
746 union smb_tcon tcon;
747 union smb_open io;
748 union smb_write wr;
749 union smb_close cl;
750 int fnum1, fnum2;
751 const char *fname1 = BASEDIR "\\test1.txt";
752 const char *fname2 = BASEDIR "\\test2.txt";
753 uint8_t c = 1;
754 uint16_t tid1, tid2;
755
756 printf("TESTING PID HANDLING WITH 2 TCONS\n");
757
758 if (!torture_setup_dir(cli, BASEDIR)) {
759 return false;
760 }
761
762 share = torture_setting_string(tctx, "share", NULL);
763 host = torture_setting_string(tctx, "host", NULL);
764
765 printf("create a second tree context on the same session\n");
766 tree = smbcli_tree_init(cli->session, tctx, false);
767
768 tcon.generic.level = RAW_TCON_TCONX;
769 tcon.tconx.in.flags = 0;
770 tcon.tconx.in.password = data_blob(NULL, 0);
771 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
772 tcon.tconx.in.device = "A:";
773 status = smb_raw_tcon(tree, tctx, &tcon);
774 CHECK_STATUS(status, NT_STATUS_OK);
775
776 tree->tid = tcon.tconx.out.tid;
777
778 tid1 = cli->tree->tid;
779 tid2 = tree->tid;
780 printf("tid1=%d tid2=%d\n", tid1, tid2);
781
782 printf("create a file using the tid1\n");
783 cli->tree->tid = tid1;
784 io.generic.level = RAW_OPEN_NTCREATEX;
785 io.ntcreatex.in.root_fid.fnum = 0;
786 io.ntcreatex.in.flags = 0;
787 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
788 io.ntcreatex.in.create_options = 0;
789 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
790 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
791 io.ntcreatex.in.alloc_size = 0;
792 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
793 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
794 io.ntcreatex.in.security_flags = 0;
795 io.ntcreatex.in.fname = fname1;
796 status = smb_raw_open(cli->tree, tctx, &io);
797 CHECK_STATUS(status, NT_STATUS_OK);
798 fnum1 = io.ntcreatex.out.file.fnum;
799
800 printf("write using the tid1\n");
801 wr.generic.level = RAW_WRITE_WRITEX;
802 wr.writex.in.file.fnum = fnum1;
803 wr.writex.in.offset = 0;
804 wr.writex.in.wmode = 0;
805 wr.writex.in.remaining = 0;
806 wr.writex.in.count = 1;
807 wr.writex.in.data = &c;
808
809 status = smb_raw_write(cli->tree, &wr);
810 CHECK_STATUS(status, NT_STATUS_OK);
811 CHECK_VALUE(wr.writex.out.nwritten, 1);
812
813 printf("create a file using the tid2\n");
814 cli->tree->tid = tid2;
815 io.generic.level = RAW_OPEN_NTCREATEX;
816 io.ntcreatex.in.root_fid.fnum = 0;
817 io.ntcreatex.in.flags = 0;
818 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
819 io.ntcreatex.in.create_options = 0;
820 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
821 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
822 io.ntcreatex.in.alloc_size = 0;
823 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
824 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
825 io.ntcreatex.in.security_flags = 0;
826 io.ntcreatex.in.fname = fname2;
827 status = smb_raw_open(cli->tree, tctx, &io);
828 CHECK_STATUS(status, NT_STATUS_OK);
829 fnum2 = io.ntcreatex.out.file.fnum;
830
831 printf("write using the tid2\n");
832 wr.generic.level = RAW_WRITE_WRITEX;
833 wr.writex.in.file.fnum = fnum2;
834 wr.writex.in.offset = 0;
835 wr.writex.in.wmode = 0;
836 wr.writex.in.remaining = 0;
837 wr.writex.in.count = 1;
838 wr.writex.in.data = &c;
839
840 status = smb_raw_write(cli->tree, &wr);
841 CHECK_STATUS(status, NT_STATUS_OK);
842 CHECK_VALUE(wr.writex.out.nwritten, 1);
843
844 printf("exit the pid\n");
845 status = smb_raw_exit(cli->session);
846 CHECK_STATUS(status, NT_STATUS_OK);
847
848 printf("the fnum1 on tid1 should not be accessible\n");
849 cli->tree->tid = tid1;
850 wr.writex.in.file.fnum = fnum1;
851 status = smb_raw_write(cli->tree, &wr);
852 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
853
854 printf("the fnum1 on tid1 should have been auto-closed\n");
855 cl.close.level = RAW_CLOSE_CLOSE;
856 cl.close.in.file.fnum = fnum1;
857 cl.close.in.write_time = 0;
858 status = smb_raw_close(cli->tree, &cl);
859 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
860
861 printf("the fnum2 on tid2 should not be accessible\n");
862 cli->tree->tid = tid2;
863 wr.writex.in.file.fnum = fnum2;
864 status = smb_raw_write(cli->tree, &wr);
865 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
866
867 printf("the fnum2 on tid2 should have been auto-closed\n");
868 cl.close.level = RAW_CLOSE_CLOSE;
869 cl.close.in.file.fnum = fnum2;
870 cl.close.in.write_time = 0;
871 status = smb_raw_close(cli->tree, &cl);
872 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
873
874done:
875 return ret;
876}
877
878
879/*
880 basic testing of session/tree context calls
881*/
882static bool torture_raw_context_int(struct torture_context *tctx,
883 struct smbcli_state *cli)
884{
885 bool ret = true;
886
887 ret &= test_session(cli, tctx);
888 ret &= test_tree(cli, tctx);
889 ret &= test_tree_ulogoff(cli, tctx);
890 ret &= test_pid_exit_only_sees_open(cli, tctx);
891 ret &= test_pid_2sess(cli, tctx);
892 ret &= test_pid_2tcon(cli, tctx);
893
894 smb_raw_exit(cli->session);
895 smbcli_deltree(cli->tree, BASEDIR);
896
897 return ret;
898}
899/*
900 basic testing of session/tree context calls
901*/
902bool torture_raw_context(struct torture_context *torture,
903 struct smbcli_state *cli)
904{
905 bool ret = true;
906 if (lpcfg_use_spnego(torture->lp_ctx)) {
907 ret &= torture_raw_context_int(torture, cli);
908 lpcfg_set_cmdline(torture->lp_ctx, "use spnego", "False");
909 }
910
911 ret &= torture_raw_context_int(torture, cli);
912
913 return ret;
914}
Note: See TracBrowser for help on using the repository browser.