r5928: Use cli_credentials in:
[jelmer/samba4-debian.git] / source / torture / raw / context.c
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "librpc/gen_ndr/ndr_security.h"
24 #include "libcli/composite/composite.h"
25 #include "lib/cmdline/popt_common.h"
26
27 #define BASEDIR "\\rawcontext"
28
29 #define CHECK_STATUS(status, correct) do { \
30         if (!NT_STATUS_EQUAL(status, correct)) { \
31                 printf("(%s) Incorrect status %s - should be %s\n", \
32                        __location__, nt_errstr(status), nt_errstr(correct)); \
33                 ret = False; \
34                 goto done; \
35         }} while (0)
36
37 #define CHECK_VALUE(v, correct) do { \
38         if ((v) != (correct)) { \
39                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
40                        __location__, #v, v, correct); \
41                 ret = False; \
42                 goto done; \
43         }} while (0)
44
45 #define CHECK_NOT_VALUE(v, correct) do { \
46         if ((v) == (correct)) { \
47                 printf("(%s) Incorrect value %s=%d - should not be %d\n", \
48                        __location__, #v, v, correct); \
49                 ret = False; \
50                 goto done; \
51         }} while (0)
52
53
54 /*
55   test session ops
56 */
57 static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
58 {
59         NTSTATUS status;
60         BOOL ret = True;
61         struct smbcli_session *session;
62         struct smbcli_session *session2;
63         struct smbcli_session *session3;
64         struct smbcli_tree *tree;
65         struct smb_composite_sesssetup setup;
66         union smb_open io;
67         union smb_write wr;
68         union smb_close cl;
69         int fnum;
70         const char *fname = BASEDIR "\\test.txt";
71         uint8_t c = 1;
72
73         printf("TESTING SESSION HANDLING\n");
74
75         if (!torture_setup_dir(cli, BASEDIR)) {
76                 return False;
77         }
78
79         printf("create a second security context on the same transport\n");
80         session = smbcli_session_init(cli->transport, mem_ctx, False);
81
82         setup.in.sesskey = cli->transport->negotiate.sesskey;
83         setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
84         setup.in.password = cli_credentials_get_password(cmdline_credentials);
85         setup.in.user = cli_credentials_get_username(cmdline_credentials);
86         setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
87
88         status = smb_composite_sesssetup(session, &setup);
89         CHECK_STATUS(status, NT_STATUS_OK);
90
91         session->vuid = setup.out.vuid;
92
93         printf("create a third security context on the same transport, with vuid set\n");
94         session2 = smbcli_session_init(cli->transport, mem_ctx, False);
95
96         session2->vuid = session->vuid;
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
100         setup.in.password = cli_credentials_get_password(cmdline_credentials);
101         setup.in.user = cli_credentials_get_username(cmdline_credentials);
102         setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
103
104         status = smb_composite_sesssetup(session2, &setup);
105         CHECK_STATUS(status, NT_STATUS_OK);
106
107         session2->vuid = setup.out.vuid;
108         printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
109         
110         CHECK_NOT_VALUE(session->vuid, session2->vuid);
111         talloc_free(session2);
112
113         if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
114                 printf("create a fourth security context on the same transport, without extended security\n");
115                 session3 = smbcli_session_init(cli->transport, mem_ctx, False);
116
117                 session3->vuid = session->vuid;
118                 setup.in.sesskey = cli->transport->negotiate.sesskey;
119                 setup.in.capabilities = 0; /* force a non extended security login (should fail) */
120
121
122                 setup.in.password = cli_credentials_get_password(cmdline_credentials);
123                 setup.in.user = cli_credentials_get_username(cmdline_credentials);
124                 setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
125
126                 status = smb_composite_sesssetup(session3, &setup);
127                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
128
129                 talloc_free(session3);
130         }
131                 
132         printf("use the same tree as the existing connection\n");
133         tree = smbcli_tree_init(session, mem_ctx, False);
134         tree->tid = cli->tree->tid;
135
136         printf("create a file using the new vuid\n");
137         io.generic.level = RAW_OPEN_NTCREATEX;
138         io.ntcreatex.in.root_fid = 0;
139         io.ntcreatex.in.flags = 0;
140         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
141         io.ntcreatex.in.create_options = 0;
142         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
143         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
144         io.ntcreatex.in.alloc_size = 0;
145         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
146         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
147         io.ntcreatex.in.security_flags = 0;
148         io.ntcreatex.in.fname = fname;
149         status = smb_raw_open(tree, mem_ctx, &io);
150         CHECK_STATUS(status, NT_STATUS_OK);
151         fnum = io.ntcreatex.out.fnum;
152
153         printf("write using the old vuid\n");
154         wr.generic.level = RAW_WRITE_WRITEX;
155         wr.writex.in.fnum = fnum;
156         wr.writex.in.offset = 0;
157         wr.writex.in.wmode = 0;
158         wr.writex.in.remaining = 0;
159         wr.writex.in.count = 1;
160         wr.writex.in.data = &c;
161
162         status = smb_raw_write(cli->tree, &wr);
163         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
164
165         printf("write with the new vuid\n");
166         status = smb_raw_write(tree, &wr);
167         CHECK_STATUS(status, NT_STATUS_OK);
168         CHECK_VALUE(wr.writex.out.nwritten, 1);
169
170         printf("logoff the new vuid\n");
171         status = smb_raw_ulogoff(session);
172         CHECK_STATUS(status, NT_STATUS_OK);
173         talloc_free(session);
174
175         printf("the new vuid should not now be accessible\n");
176         status = smb_raw_write(tree, &wr);
177         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
178
179         printf("the fnum should have been auto-closed\n");
180         cl.close.level = RAW_CLOSE_CLOSE;
181         cl.close.in.fnum = fnum;
182         cl.close.in.write_time = 0;
183         status = smb_raw_close(cli->tree, &cl);
184         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
185
186         talloc_free(tree);
187         
188 done:
189         return ret;
190 }
191
192
193 /*
194   test tree ops
195 */
196 static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
197 {
198         NTSTATUS status;
199         BOOL ret = True;
200         const char *share;
201         struct smbcli_tree *tree;
202         union smb_tcon tcon;
203         union smb_open io;
204         union smb_write wr;
205         union smb_close cl;
206         int fnum;
207         const char *fname = BASEDIR "\\test.txt";
208         uint8_t c = 1;
209
210         printf("TESTING TREE HANDLING\n");
211
212         if (!torture_setup_dir(cli, BASEDIR)) {
213                 return False;
214         }
215
216         share = lp_parm_string(-1, "torture", "share");
217         
218         printf("create a second tree context on the same session\n");
219         tree = smbcli_tree_init(cli->session, mem_ctx, False);
220
221         tcon.generic.level = RAW_TCON_TCONX;
222         tcon.tconx.in.flags = 0;
223         tcon.tconx.in.password = data_blob(NULL, 0);
224         tcon.tconx.in.path = share;
225         tcon.tconx.in.device = "A:";    
226         status = smb_tree_connect(tree, mem_ctx, &tcon);
227         CHECK_STATUS(status, NT_STATUS_OK);
228
229         tree->tid = tcon.tconx.out.tid;
230         printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
231
232         printf("try a tconx with a bad device type\n");
233         tcon.tconx.in.device = "FOO";   
234         status = smb_tree_connect(tree, mem_ctx, &tcon);
235         CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
236
237
238         printf("create a file using the new tid\n");
239         io.generic.level = RAW_OPEN_NTCREATEX;
240         io.ntcreatex.in.root_fid = 0;
241         io.ntcreatex.in.flags = 0;
242         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
243         io.ntcreatex.in.create_options = 0;
244         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
245         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
246         io.ntcreatex.in.alloc_size = 0;
247         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
248         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
249         io.ntcreatex.in.security_flags = 0;
250         io.ntcreatex.in.fname = fname;
251         status = smb_raw_open(tree, mem_ctx, &io);
252         CHECK_STATUS(status, NT_STATUS_OK);
253         fnum = io.ntcreatex.out.fnum;
254
255         printf("write using the old tid\n");
256         wr.generic.level = RAW_WRITE_WRITEX;
257         wr.writex.in.fnum = fnum;
258         wr.writex.in.offset = 0;
259         wr.writex.in.wmode = 0;
260         wr.writex.in.remaining = 0;
261         wr.writex.in.count = 1;
262         wr.writex.in.data = &c;
263
264         status = smb_raw_write(cli->tree, &wr);
265         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
266
267         printf("write with the new tid\n");
268         status = smb_raw_write(tree, &wr);
269         CHECK_STATUS(status, NT_STATUS_OK);
270         CHECK_VALUE(wr.writex.out.nwritten, 1);
271
272         printf("disconnect the new tid\n");
273         status = smb_tree_disconnect(tree);
274         CHECK_STATUS(status, NT_STATUS_OK);
275
276         printf("the new tid should not now be accessible\n");
277         status = smb_raw_write(tree, &wr);
278         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
279
280         printf("the fnum should have been auto-closed\n");
281         cl.close.level = RAW_CLOSE_CLOSE;
282         cl.close.in.fnum = fnum;
283         cl.close.in.write_time = 0;
284         status = smb_raw_close(cli->tree, &cl);
285         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
286
287         /* close down the new tree */
288         talloc_free(tree);
289         
290 done:
291         return ret;
292 }
293
294
295 /*
296   test pid ops
297 */
298 static BOOL test_pid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
299 {
300         NTSTATUS status;
301         BOOL ret = True;
302         union smb_open io;
303         union smb_write wr;
304         union smb_close cl;
305         int fnum;
306         const char *fname = BASEDIR "\\test.txt";
307         uint8_t c = 1;
308         uint16_t pid1, pid2;
309
310         printf("TESTING PID HANDLING\n");
311
312         if (!torture_setup_dir(cli, BASEDIR)) {
313                 return False;
314         }
315
316         printf("create a second pid\n");
317         pid1 = cli->session->pid;
318         pid2 = pid1+1;
319
320         printf("pid1=%d pid2=%d\n", pid1, pid2);
321
322         printf("create a file using the new pid\n");
323         cli->session->pid = pid2;
324         io.generic.level = RAW_OPEN_NTCREATEX;
325         io.ntcreatex.in.root_fid = 0;
326         io.ntcreatex.in.flags = 0;
327         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
328         io.ntcreatex.in.create_options = 0;
329         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
330         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
331         io.ntcreatex.in.alloc_size = 0;
332         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
333         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
334         io.ntcreatex.in.security_flags = 0;
335         io.ntcreatex.in.fname = fname;
336         status = smb_raw_open(cli->tree, mem_ctx, &io);
337         CHECK_STATUS(status, NT_STATUS_OK);
338         fnum = io.ntcreatex.out.fnum;
339
340         printf("write using the old pid\n");
341         cli->session->pid = pid1;
342         wr.generic.level = RAW_WRITE_WRITEX;
343         wr.writex.in.fnum = fnum;
344         wr.writex.in.offset = 0;
345         wr.writex.in.wmode = 0;
346         wr.writex.in.remaining = 0;
347         wr.writex.in.count = 1;
348         wr.writex.in.data = &c;
349
350         status = smb_raw_write(cli->tree, &wr);
351         CHECK_STATUS(status, NT_STATUS_OK);
352         CHECK_VALUE(wr.writex.out.nwritten, 1);
353
354         printf("write with the new pid\n");
355         cli->session->pid = pid2;
356         status = smb_raw_write(cli->tree, &wr);
357         CHECK_STATUS(status, NT_STATUS_OK);
358         CHECK_VALUE(wr.writex.out.nwritten, 1);
359
360         printf("exit the old pid\n");
361         cli->session->pid = pid1;
362         status = smb_raw_exit(cli->session);
363         CHECK_STATUS(status, NT_STATUS_OK);
364
365         printf("the fnum should still be accessible\n");
366         cli->session->pid = pid1;
367         status = smb_raw_write(cli->tree, &wr);
368         CHECK_STATUS(status, NT_STATUS_OK);
369         CHECK_VALUE(wr.writex.out.nwritten, 1);
370
371         printf("exit the new pid\n");
372         cli->session->pid = pid2;
373         status = smb_raw_exit(cli->session);
374         CHECK_STATUS(status, NT_STATUS_OK);
375
376         printf("the fnum should not now be accessible\n");
377         cli->session->pid = pid1;
378         status = smb_raw_write(cli->tree, &wr);
379         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
380
381         printf("the fnum should have been auto-closed\n");
382         cl.close.level = RAW_CLOSE_CLOSE;
383         cl.close.in.fnum = fnum;
384         cl.close.in.write_time = 0;
385         status = smb_raw_close(cli->tree, &cl);
386         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
387
388 done:
389         return ret;
390 }
391
392
393 /* 
394    basic testing of session/tree context calls
395 */
396 BOOL torture_raw_context(void)
397 {
398         struct smbcli_state *cli;
399         BOOL ret = True;
400         TALLOC_CTX *mem_ctx;
401
402         lp_set_cmdline("use spnego", "False");
403
404         if (!torture_open_connection(&cli)) {
405                 return False;
406         }
407
408         mem_ctx = talloc_init("torture_raw_context");
409
410         if (!test_session(cli, mem_ctx)) {
411                 ret = False;
412         }
413
414         if (!test_tree(cli, mem_ctx)) {
415                 ret = False;
416         }
417
418         if (!test_pid(cli, mem_ctx)) {
419                 ret = False;
420         }
421
422         smb_raw_exit(cli->session);
423         smbcli_deltree(cli->tree, BASEDIR);
424
425         torture_close_connection(cli);
426         talloc_free(mem_ctx);
427
428         return ret;
429 }