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/>.
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
)
36 struct smb_composite_sesssetup io
;
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,
51 FILE_ATTRIBUTE_NORMAL
,
52 NTCREATEX_SHARE_ACCESS_NONE
,
53 NTCREATEX_DISP_OPEN_IF
,
54 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
,
56 torture_assert_ntstatus_ok_goto(tctx
, smbcli_nt_error(cli
->tree
), ok
,
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");
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");
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");
83 status
= smbcli_close(cli
->tree
, fnum
);
84 torture_assert_ntstatus_ok(tctx
, status
, "close");
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
)
96 static bool test_session_reauth2(struct torture_context
*tctx
,
97 struct smbcli_state
*cli
)
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
;
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",
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
,
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
;
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 "
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(
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(
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 "
223 status
= smbcli_close(cli
->tree
, fnum
);
224 torture_assert_ntstatus_ok(tctx
, status
, "close failed");
229 static bool test_session_expire1(struct torture_context
*tctx
)
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
;
240 union smb_fileinfo qfinfo
;
243 struct smb_composite_sesssetup io_sesssetup
;
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!");
253 "smb2.session.expire1 requires "
254 "--use-kerberos=required!");
257 torture_assert_int_equal(tctx
,
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
,
270 lpcfg_smb_ports(tctx
->lp_ctx
),
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,
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 */
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");
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(),
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
,
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
,
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");
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
,
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(),
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
,
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");
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");
428 smbcli_close(cli
->tree
, fnum
);
432 lpcfg_set_option(tctx
->lp_ctx
, "gensec_gssapi:requested_life_time=0");
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
);