libcli:util: Update HRESULT definitions
[Samba.git] / source4 / torture / raw / session.c
blob76ae8089240d13089255a275a32420eb7286d21c
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for session setup operations
4 Copyright (C) Gregor Beck 2012
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.
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, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "torture.h"
22 #include "libcli/libcli.h"
23 #include "torture/raw/proto.h"
24 #include "smb_composite/smb_composite.h"
25 #include "lib/cmdline/cmdline.h"
26 #include "param/param.h"
27 #include "torture/util.h"
28 #include "auth/credentials/credentials.h"
29 #include "libcli/resolve/resolve.h"
32 static bool test_session_reauth1(struct torture_context *tctx,
33 struct smbcli_state *cli)
35 NTSTATUS status;
36 struct smb_composite_sesssetup io;
37 int fnum, num;
38 const int dlen = 255;
39 char *data;
40 char fname[256];
41 char buf[dlen+1];
42 bool ok = true;
43 uint16_t vuid1 = cli->session->vuid;
45 data = generate_random_str(tctx, dlen);
46 torture_assert(tctx, (data != NULL), "memory allocation failed");
47 snprintf(fname, sizeof(fname), "raw_session_reconnect_%.8s.dat", data);
49 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
50 SEC_RIGHTS_FILE_ALL,
51 FILE_ATTRIBUTE_NORMAL,
52 NTCREATEX_SHARE_ACCESS_NONE,
53 NTCREATEX_DISP_OPEN_IF,
54 NTCREATEX_OPTIONS_DELETE_ON_CLOSE,
55 0);
56 torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ok,
57 done, "create file");
58 torture_assert_goto(tctx, fnum > 0, ok, done, "create file");
60 num = smbcli_smbwrite(cli->tree, fnum, data, 0, dlen);
61 torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "write file");
63 ZERO_STRUCT(io);
64 io.in.sesskey = cli->transport->negotiate.sesskey;
65 io.in.capabilities = cli->transport->negotiate.capabilities;
66 io.in.credentials = samba_cmdline_get_creds();
67 io.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
68 io.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
69 status = smb_composite_sesssetup(cli->session, &io);
70 torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "setup2");
71 torture_assert_int_equal_goto(tctx, io.out.vuid, vuid1, ok, done, "setup2");
73 buf[dlen] = '\0';
75 num = smbcli_read(cli->tree, fnum, &buf, 0, dlen);
76 torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "read file");
77 torture_assert_str_equal_goto(tctx, buf, data, ok, done, "read file");
79 done:
80 talloc_free(data);
82 if (fnum > 0) {
83 status = smbcli_close(cli->tree, fnum);
84 torture_assert_ntstatus_ok(tctx, status, "close");
86 return ok;
89 static bool test_session_reauth2_oplock_timeout(
90 struct smbcli_transport *transport, uint16_t tid, uint16_t fnum,
91 uint8_t level, void *private_data)
93 return true;
96 static bool test_session_reauth2(struct torture_context *tctx,
97 struct smbcli_state *cli)
99 char *random_string;
100 char *fname;
101 union smb_open io_open;
102 struct smb_composite_sesssetup io_sesssetup;
103 union smb_fileinfo io_qsecdesc;
104 struct smbcli_request *req;
105 struct cli_credentials *anon_creds;
106 NTSTATUS status;
107 uint16_t fnum;
108 ssize_t nwritten;
109 uint16_t vuid1 = cli->session->vuid;
111 random_string = generate_random_str(tctx, 8);
112 torture_assert(tctx, (random_string != NULL),
113 "memory allocation failed");
114 fname = talloc_asprintf(tctx, "raw_session_reauth2_%s.dat",
115 random_string);
116 talloc_free(random_string);
117 torture_assert(tctx, (fname != NULL), "memory allocation failed");
119 smbcli_unlink(cli->tree, fname);
120 smbcli_oplock_handler(cli->transport,
121 test_session_reauth2_oplock_timeout,
122 cli->tree);
125 base ntcreatex parms
127 ZERO_STRUCT(io_open);
128 io_open.generic.level = RAW_OPEN_NTCREATEX;
129 io_open.ntcreatex.in.root_fid.fnum = 0;
130 io_open.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
131 SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
132 io_open.ntcreatex.in.alloc_size = 0;
133 io_open.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
134 io_open.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
135 NTCREATEX_SHARE_ACCESS_WRITE;
136 io_open.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
137 io_open.ntcreatex.in.create_options = 0;
138 io_open.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
139 io_open.ntcreatex.in.security_flags = 0;
140 io_open.ntcreatex.in.fname = fname;
142 torture_comment(tctx, "open with batch oplock\n");
143 io_open.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
144 NTCREATEX_FLAGS_REQUEST_OPLOCK |
145 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
147 status = smb_raw_open(cli->tree, tctx, &io_open);
148 torture_assert_ntstatus_ok(tctx, status, "smb_raw_open failed");
150 fnum = io_open.ntcreatex.out.file.fnum;
151 torture_assert(
152 tctx,
153 (io_open.ntcreatex.out.oplock_level == BATCH_OPLOCK_RETURN),
154 "did not get batch oplock");
156 io_open.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
157 req = smb_raw_open_send(cli->tree, &io_open);
158 torture_assert(tctx, (req != NULL), "memory allocation failed");
161 * Make sure the open went through
163 status = smbcli_chkpath(cli->tree, "\\");
164 torture_assert_ntstatus_ok(tctx, status, "smb_chkpath failed");
166 status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
167 torture_assert_ntstatus_ok(tctx, status, "could not set delete on "
168 "close");
170 anon_creds = cli_credentials_init_anon(tctx);
171 torture_assert(tctx, (anon_creds != NULL), "memory allocation failed");
173 ZERO_STRUCT(io_sesssetup);
174 io_sesssetup.in.sesskey = cli->transport->negotiate.sesskey;
175 io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
176 io_sesssetup.in.credentials = anon_creds;
177 io_sesssetup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
178 io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(
179 tctx, tctx->lp_ctx);
180 status = smb_composite_sesssetup(cli->session, &io_sesssetup);
181 torture_assert_ntstatus_ok(tctx, status, "setup2 failed");
182 torture_assert_int_equal(tctx, io_sesssetup.out.vuid, vuid1, "setup2");
184 status = smbcli_close(cli->tree, fnum);
185 torture_assert_ntstatus_ok(tctx, status, "close failed");
187 status = smb_raw_open_recv(req, tctx, &io_open);
188 torture_assert_ntstatus_ok(tctx, status, "2nd open failed");
190 fnum = io_open.ntcreatex.out.file.fnum;
192 nwritten = smbcli_write(cli->tree, fnum, 0, fname, 0, strlen(fname));
193 torture_assert(tctx, (nwritten == strlen(fname)),
194 "smbcli_write failed");
196 ZERO_STRUCT(io_qsecdesc);
197 io_qsecdesc.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
198 io_qsecdesc.query_secdesc.in.file.fnum = fnum;
199 io_qsecdesc.query_secdesc.in.secinfo_flags = SECINFO_OWNER;
200 status = smb_raw_fileinfo(cli->tree, tctx, &io_qsecdesc);
201 torture_assert_ntstatus_equal(
202 tctx, status, NT_STATUS_ACCESS_DENIED,
203 "anon qsecdesc did not return ACCESS_DENIED");
205 ZERO_STRUCT(io_sesssetup);
206 io_sesssetup.in.sesskey = cli->transport->negotiate.sesskey;
207 io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
208 io_sesssetup.in.credentials = samba_cmdline_get_creds();
209 io_sesssetup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
210 io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(
211 tctx, tctx->lp_ctx);
212 status = smb_composite_sesssetup(cli->session, &io_sesssetup);
213 torture_assert_ntstatus_ok(tctx, status, "setup3 failed");
214 torture_assert_int_equal(tctx, io_sesssetup.out.vuid, vuid1, "setup2");
216 status = smb_raw_fileinfo(cli->tree, tctx, &io_qsecdesc);
217 torture_assert_ntstatus_ok(tctx, status, "2nd qsecdesc failed");
219 status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
220 torture_assert_ntstatus_ok(tctx, status, "could not set delete on "
221 "close");
223 status = smbcli_close(cli->tree, fnum);
224 torture_assert_ntstatus_ok(tctx, status, "close failed");
226 return true;
229 static bool test_session_expire1(struct torture_context *tctx)
231 NTSTATUS status;
232 bool ret = false;
233 struct smbcli_options options;
234 struct smbcli_session_options session_options;
235 const char *host = torture_setting_string(tctx, "host", NULL);
236 const char *share = torture_setting_string(tctx, "share", NULL);
237 struct smbcli_state *cli = NULL;
238 enum credentials_use_kerberos use_kerberos;
239 char fname[256];
240 union smb_fileinfo qfinfo;
241 uint16_t vuid;
242 uint16_t fnum = 0;
243 struct smb_composite_sesssetup io_sesssetup;
244 size_t i;
246 use_kerberos = cli_credentials_get_kerberos_state(
247 samba_cmdline_get_creds());
248 if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
249 torture_warning(tctx,
250 "smb2.session.expire1 requires "
251 "--use-kerberos=required!");
252 torture_skip(tctx,
253 "smb2.session.expire1 requires "
254 "--use-kerberos=required!");
257 torture_assert_int_equal(tctx,
258 use_kerberos,
259 CRED_USE_KERBEROS_REQUIRED,
260 "please use --use-kerberos=required");
262 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
264 lpcfg_smbcli_options(tctx->lp_ctx, &options);
266 lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
268 status = smbcli_full_connection(tctx, &cli,
269 host,
270 lpcfg_smb_ports(tctx->lp_ctx),
271 share, NULL,
272 lpcfg_socket_options(tctx->lp_ctx),
273 samba_cmdline_get_creds(),
274 lpcfg_resolve_context(tctx->lp_ctx),
275 tctx->ev, &options, &session_options,
276 lpcfg_gensec_settings(tctx, tctx->lp_ctx));
277 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
278 "smbcli_full_connection failed");
280 vuid = cli->session->vuid;
282 /* Add some random component to the file name. */
283 snprintf(fname, 256, "session_expire1_%s.dat",
284 generate_random_str(tctx, 8));
286 smbcli_unlink(cli->tree, fname);
288 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
289 SEC_RIGHTS_FILE_ALL,
290 FILE_ATTRIBUTE_NORMAL,
291 NTCREATEX_SHARE_ACCESS_NONE,
292 NTCREATEX_DISP_OPEN_IF,
293 NTCREATEX_OPTIONS_DELETE_ON_CLOSE,
295 torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ret,
296 done, "create file");
297 torture_assert_goto(tctx, fnum > 0, ret, done, "create file");
299 /* get the access information */
301 ZERO_STRUCT(qfinfo);
303 qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
304 qfinfo.access_information.in.file.fnum = fnum;
306 for (i=0; i < 2; i++) {
307 torture_comment(tctx, "query info => OK\n");
308 ZERO_STRUCT(qfinfo.access_information.out);
309 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
310 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
311 "raw_fileinfo failed");
313 torture_comment(tctx, "sleep 10 seconds\n");
314 smb_msleep(10*1000);
318 * the krb5 library may not handle expired creds
319 * well, lets start with an empty ccache.
321 cli_credentials_invalidate_ccache(samba_cmdline_get_creds(),
322 CRED_SPECIFIED);
325 * now with CAP_DYNAMIC_REAUTH
327 * This should trigger NT_STATUS_NETWORK_SESSION_EXPIRED
329 ZERO_STRUCT(io_sesssetup);
330 io_sesssetup.in.sesskey = cli->transport->negotiate.sesskey;
331 io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
332 io_sesssetup.in.capabilities |= CAP_DYNAMIC_REAUTH;
333 io_sesssetup.in.credentials = samba_cmdline_get_creds();
334 io_sesssetup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx);
335 io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(tctx,
336 tctx->lp_ctx);
338 torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
339 ZERO_STRUCT(io_sesssetup.out);
340 status = smb_composite_sesssetup(cli->session, &io_sesssetup);
341 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
342 "reauth failed");
343 torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
344 ret, done, "reauth");
346 for (i=0; i < 2; i++) {
347 torture_comment(tctx, "query info => OK\n");
348 ZERO_STRUCT(qfinfo.access_information.out);
349 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
350 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
351 "raw_fileinfo failed");
353 torture_comment(tctx, "sleep 10 seconds\n");
354 smb_msleep(10*1000);
356 torture_comment(tctx, "query info => EXPIRED\n");
357 ZERO_STRUCT(qfinfo.access_information.out);
358 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
359 torture_assert_ntstatus_equal_goto(tctx, status,
360 NT_STATUS_NETWORK_SESSION_EXPIRED,
361 ret, done, "raw_fileinfo expired");
364 * the krb5 library may not handle expired creds
365 * well, lets start with an empty ccache.
367 cli_credentials_invalidate_ccache(
368 samba_cmdline_get_creds(), CRED_SPECIFIED);
370 torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
371 ZERO_STRUCT(io_sesssetup.out);
372 status = smb_composite_sesssetup(cli->session, &io_sesssetup);
373 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
374 "reauth failed");
375 torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
376 ret, done, "reauth");
379 torture_comment(tctx, "query info => OK\n");
380 ZERO_STRUCT(qfinfo.access_information.out);
381 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
382 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
383 "raw_fileinfo failed");
386 * the krb5 library may not handle expired creds
387 * well, lets start with an empty ccache.
389 cli_credentials_invalidate_ccache(samba_cmdline_get_creds(),
390 CRED_SPECIFIED);
393 * now without CAP_DYNAMIC_REAUTH
395 * This should not trigger NT_STATUS_NETWORK_SESSION_EXPIRED
397 torture_comment(tctx, "reauth without CAP_DYNAMIC_REAUTH => OK\n");
398 io_sesssetup.in.capabilities &= ~CAP_DYNAMIC_REAUTH;
400 ZERO_STRUCT(io_sesssetup.out);
401 status = smb_composite_sesssetup(cli->session, &io_sesssetup);
402 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
403 "reauth failed");
404 torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
405 ret, done, "reauth");
407 for (i=0; i < 2; i++) {
408 torture_comment(tctx, "query info => OK\n");
410 ZERO_STRUCT(qfinfo.access_information.out);
411 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
412 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
413 "raw_fileinfo failed");
415 torture_comment(tctx, "sleep 5 seconds\n");
416 smb_msleep(5*1000);
419 torture_comment(tctx, "query info => OK\n");
420 ZERO_STRUCT(qfinfo.access_information.out);
421 status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
422 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
423 "raw_fileinfo failed");
425 ret = true;
426 done:
427 if (fnum > 0) {
428 smbcli_close(cli->tree, fnum);
431 talloc_free(cli);
432 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
433 return ret;
436 struct torture_suite *torture_raw_session(TALLOC_CTX *mem_ctx)
438 struct torture_suite *suite = torture_suite_create(mem_ctx, "session");
439 suite->description = talloc_strdup(suite, "RAW-SESSION tests");
441 torture_suite_add_1smb_test(suite, "reauth1", test_session_reauth1);
442 torture_suite_add_1smb_test(suite, "reauth2", test_session_reauth2);
443 torture_suite_add_simple_test(suite, "expire1", test_session_expire1);
445 return suite;