2 Unix SMB/CIFS implementation.
3 test suite for session setup operations
4 Copyright (C) Andrew Tridgell 2003
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define BASEDIR "\\rawcontext"
25 #define CHECK_STATUS(status, correct) do { \
26 if (!NT_STATUS_EQUAL(status, correct)) { \
27 printf("(%d) Incorrect status %s - should be %s\n", \
28 __LINE__, nt_errstr(status), nt_errstr(correct)); \
33 #define CHECK_VALUE(v, correct) do { \
34 if ((v) != (correct)) { \
35 printf("(%d) Incorrect value %s=%d - should be %d\n", \
36 __LINE__, #v, v, correct); \
45 static BOOL test_session(struct cli_state *cli, TALLOC_CTX *mem_ctx)
49 char *username, *domain, *password;
50 struct cli_session *session;
51 struct cli_tree *tree;
52 union smb_sesssetup setup;
57 const char *fname = BASEDIR "\\test.txt";
60 printf("TESTING SESSION HANDLING\n");
62 if (cli_deltree(cli->tree, BASEDIR) == -1 ||
63 NT_STATUS_IS_ERR(cli_mkdir(cli->tree, BASEDIR))) {
64 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
68 username = lp_parm_string(-1, "torture", "username");
69 password = lp_parm_string(-1, "torture", "password");
70 domain = lp_workgroup();
72 printf("create a second security context on the same transport\n");
73 session = cli_session_init(cli->transport);
74 setup.generic.level = RAW_SESSSETUP_GENERIC;
75 setup.generic.in.sesskey = cli->transport->negotiate.sesskey;
76 setup.generic.in.capabilities = 0; /* ignored in secondary session setup */
77 setup.generic.in.password = password;
78 setup.generic.in.user = username;
79 setup.generic.in.domain = domain;
81 status = smb_raw_session_setup(session, mem_ctx, &setup);
82 CHECK_STATUS(status, NT_STATUS_OK);
84 session->vuid = setup.generic.out.vuid;
86 printf("use the same tree as the existing connection\n");
87 tree = cli_tree_init(session);
88 tree->tid = cli->tree->tid;
89 cli->tree->reference_count++;
91 printf("vuid1=%d vuid2=%d\n", cli->session->vuid, session->vuid);
93 printf("create a file using the new vuid\n");
94 io.generic.level = RAW_OPEN_NTCREATEX;
95 io.ntcreatex.in.root_fid = 0;
96 io.ntcreatex.in.flags = 0;
97 io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
98 io.ntcreatex.in.create_options = 0;
99 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
100 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
101 io.ntcreatex.in.alloc_size = 0;
102 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
103 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
104 io.ntcreatex.in.security_flags = 0;
105 io.ntcreatex.in.fname = fname;
106 status = smb_raw_open(tree, mem_ctx, &io);
107 CHECK_STATUS(status, NT_STATUS_OK);
108 fnum = io.ntcreatex.out.fnum;
110 printf("write using the old vuid\n");
111 wr.generic.level = RAW_WRITE_WRITEX;
112 wr.writex.in.fnum = fnum;
113 wr.writex.in.offset = 0;
114 wr.writex.in.wmode = 0;
115 wr.writex.in.remaining = 0;
116 wr.writex.in.count = 1;
117 wr.writex.in.data = &c;
119 status = smb_raw_write(cli->tree, &wr);
120 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
122 printf("write with the new vuid\n");
123 status = smb_raw_write(tree, &wr);
124 CHECK_STATUS(status, NT_STATUS_OK);
125 CHECK_VALUE(wr.writex.out.nwritten, 1);
127 printf("logoff the new vuid\n");
128 status = smb_raw_ulogoff(session);
129 CHECK_STATUS(status, NT_STATUS_OK);
131 printf("the new vuid should not now be accessible\n");
132 status = smb_raw_write(tree, &wr);
133 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
135 printf("the fnum should have been auto-closed\n");
136 cl.close.level = RAW_CLOSE_CLOSE;
137 cl.close.in.fnum = fnum;
138 cl.close.in.write_time = 0;
139 status = smb_raw_close(cli->tree, &cl);
140 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
142 /* close down the new tree, which will also close the session
143 as the reference count will be 0 */
144 cli_tree_close(tree);
154 static BOOL test_tree(struct cli_state *cli, TALLOC_CTX *mem_ctx)
159 struct cli_tree *tree;
165 const char *fname = BASEDIR "\\test.txt";
168 printf("TESTING TREE HANDLING\n");
170 if (cli_deltree(cli->tree, BASEDIR) == -1 ||
171 NT_STATUS_IS_ERR(cli_mkdir(cli->tree, BASEDIR))) {
172 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
176 share = lp_parm_string(-1, "torture", "share");
178 printf("create a second tree context on the same session\n");
179 tree = cli_tree_init(cli->session);
181 tcon.generic.level = RAW_TCON_TCONX;
182 tcon.tconx.in.flags = 0;
183 tcon.tconx.in.password = data_blob(NULL, 0);
184 tcon.tconx.in.path = share;
185 tcon.tconx.in.device = "A:";
186 status = smb_tree_connect(tree, mem_ctx, &tcon);
187 CHECK_STATUS(status, NT_STATUS_OK);
189 tree->tid = tcon.tconx.out.cnum;
190 printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
192 printf("try a tconx with a bad device type\n");
193 tcon.tconx.in.device = "FOO";
194 status = smb_tree_connect(tree, mem_ctx, &tcon);
195 CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
198 printf("create a file using the new tid\n");
199 io.generic.level = RAW_OPEN_NTCREATEX;
200 io.ntcreatex.in.root_fid = 0;
201 io.ntcreatex.in.flags = 0;
202 io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
203 io.ntcreatex.in.create_options = 0;
204 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
205 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
206 io.ntcreatex.in.alloc_size = 0;
207 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
208 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
209 io.ntcreatex.in.security_flags = 0;
210 io.ntcreatex.in.fname = fname;
211 status = smb_raw_open(tree, mem_ctx, &io);
212 CHECK_STATUS(status, NT_STATUS_OK);
213 fnum = io.ntcreatex.out.fnum;
215 printf("write using the old tid\n");
216 wr.generic.level = RAW_WRITE_WRITEX;
217 wr.writex.in.fnum = fnum;
218 wr.writex.in.offset = 0;
219 wr.writex.in.wmode = 0;
220 wr.writex.in.remaining = 0;
221 wr.writex.in.count = 1;
222 wr.writex.in.data = &c;
224 status = smb_raw_write(cli->tree, &wr);
225 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
227 printf("write with the new tid\n");
228 status = smb_raw_write(tree, &wr);
229 CHECK_STATUS(status, NT_STATUS_OK);
230 CHECK_VALUE(wr.writex.out.nwritten, 1);
232 printf("disconnect the new tid\n");
233 status = smb_tree_disconnect(tree);
234 CHECK_STATUS(status, NT_STATUS_OK);
236 printf("the new tid should not now be accessible\n");
237 status = smb_raw_write(tree, &wr);
238 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
240 printf("the fnum should have been auto-closed\n");
241 cl.close.level = RAW_CLOSE_CLOSE;
242 cl.close.in.fnum = fnum;
243 cl.close.in.write_time = 0;
244 status = smb_raw_close(cli->tree, &cl);
245 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
247 /* close down the new tree */
248 cli_tree_close(tree);
258 static BOOL test_pid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
266 const char *fname = BASEDIR "\\test.txt";
270 printf("TESTING PID HANDLING\n");
272 if (cli_deltree(cli->tree, BASEDIR) == -1 ||
273 NT_STATUS_IS_ERR(cli_mkdir(cli->tree, BASEDIR))) {
274 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
278 printf("create a second pid\n");
279 pid1 = cli->session->pid;
282 printf("pid1=%d pid2=%d\n", pid1, pid2);
284 printf("create a file using the new pid\n");
285 cli->session->pid = pid2;
286 io.generic.level = RAW_OPEN_NTCREATEX;
287 io.ntcreatex.in.root_fid = 0;
288 io.ntcreatex.in.flags = 0;
289 io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
290 io.ntcreatex.in.create_options = 0;
291 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
292 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
293 io.ntcreatex.in.alloc_size = 0;
294 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
295 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
296 io.ntcreatex.in.security_flags = 0;
297 io.ntcreatex.in.fname = fname;
298 status = smb_raw_open(cli->tree, mem_ctx, &io);
299 CHECK_STATUS(status, NT_STATUS_OK);
300 fnum = io.ntcreatex.out.fnum;
302 printf("write using the old pid\n");
303 cli->session->pid = pid1;
304 wr.generic.level = RAW_WRITE_WRITEX;
305 wr.writex.in.fnum = fnum;
306 wr.writex.in.offset = 0;
307 wr.writex.in.wmode = 0;
308 wr.writex.in.remaining = 0;
309 wr.writex.in.count = 1;
310 wr.writex.in.data = &c;
312 status = smb_raw_write(cli->tree, &wr);
313 CHECK_STATUS(status, NT_STATUS_OK);
314 CHECK_VALUE(wr.writex.out.nwritten, 1);
316 printf("write with the new pid\n");
317 cli->session->pid = pid2;
318 status = smb_raw_write(cli->tree, &wr);
319 CHECK_STATUS(status, NT_STATUS_OK);
320 CHECK_VALUE(wr.writex.out.nwritten, 1);
322 printf("exit the old pid\n");
323 cli->session->pid = pid1;
324 status = smb_raw_exit(cli->session);
325 CHECK_STATUS(status, NT_STATUS_OK);
327 printf("the fnum should still be accessible\n");
328 cli->session->pid = pid1;
329 status = smb_raw_write(cli->tree, &wr);
330 CHECK_STATUS(status, NT_STATUS_OK);
331 CHECK_VALUE(wr.writex.out.nwritten, 1);
333 printf("exit the new pid\n");
334 cli->session->pid = pid2;
335 status = smb_raw_exit(cli->session);
336 CHECK_STATUS(status, NT_STATUS_OK);
338 printf("the fnum should not now be accessible\n");
339 cli->session->pid = pid1;
340 status = smb_raw_write(cli->tree, &wr);
341 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
343 printf("the fnum should have been auto-closed\n");
344 cl.close.level = RAW_CLOSE_CLOSE;
345 cl.close.in.fnum = fnum;
346 cl.close.in.write_time = 0;
347 status = smb_raw_close(cli->tree, &cl);
348 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
356 basic testing of session/tree context calls
358 BOOL torture_raw_context(int dummy)
360 struct cli_state *cli;
364 if (!torture_open_connection(&cli)) {
368 mem_ctx = talloc_init("torture_raw_context");
370 if (!test_session(cli, mem_ctx)) {
374 if (!test_tree(cli, mem_ctx)) {
378 if (!test_pid(cli, mem_ctx)) {
382 smb_raw_exit(cli->session);
383 cli_deltree(cli->tree, BASEDIR);
385 torture_close_connection(cli);
386 talloc_destroy(mem_ctx);