Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Initial test for the smb2 client lib
4 : Copyright (C) Volker Lendecke 2011
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 "torture/proto.h"
22 : #include "client.h"
23 : #include "trans2.h"
24 : #include "../libcli/smb/smbXcli_base.h"
25 : #include "libcli/security/security.h"
26 : #include "libsmb/proto.h"
27 : #include "auth/credentials/credentials.h"
28 : #include "auth/gensec/gensec.h"
29 : #include "auth_generic.h"
30 : #include "../librpc/ndr/libndr.h"
31 : #include "libsmb/clirap.h"
32 : #include "libsmb/cli_smb2_fnum.h"
33 :
34 : extern fstring host, workgroup, share, password, username, myname;
35 : extern struct cli_credentials *torture_creds;
36 :
37 1 : bool run_smb2_basic(int dummy)
38 : {
39 : struct cli_state *cli;
40 : NTSTATUS status;
41 : uint64_t fid_persistent, fid_volatile;
42 1 : const char *hello = "Hello, world\n";
43 : uint8_t *result;
44 : uint32_t nread;
45 : uint8_t *dir_data;
46 : uint32_t dir_data_length;
47 1 : uint32_t saved_tid = 0;
48 1 : struct smbXcli_tcon *saved_tcon = NULL;
49 1 : uint64_t saved_uid = 0;
50 :
51 1 : printf("Starting SMB2-BASIC\n");
52 :
53 1 : if (!torture_init_connection(&cli)) {
54 0 : return false;
55 : }
56 :
57 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
58 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
59 1 : if (!NT_STATUS_IS_OK(status)) {
60 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
61 0 : return false;
62 : }
63 :
64 1 : status = cli_session_setup_creds(cli, torture_creds);
65 1 : if (!NT_STATUS_IS_OK(status)) {
66 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
67 0 : return false;
68 : }
69 :
70 1 : status = cli_tree_connect(cli, share, "?????", NULL);
71 1 : if (!NT_STATUS_IS_OK(status)) {
72 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
73 0 : return false;
74 : }
75 :
76 1 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
77 1 : cli->smb2.tcon, "smb2-basic.txt",
78 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
79 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
80 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
81 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
82 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
83 : FILE_CREATE, /* create_disposition, */
84 : FILE_DELETE_ON_CLOSE, /* create_options, */
85 : NULL, /* smb2_create_blobs *blobs */
86 : &fid_persistent,
87 : &fid_volatile,
88 : NULL, NULL, NULL);
89 1 : if (!NT_STATUS_IS_OK(status)) {
90 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
91 0 : return false;
92 : }
93 :
94 3 : status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
95 2 : cli->smb2.tcon, strlen(hello), 0, fid_persistent,
96 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
97 1 : if (!NT_STATUS_IS_OK(status)) {
98 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
99 0 : return false;
100 : }
101 :
102 2 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
103 1 : cli->smb2.tcon, fid_persistent, fid_volatile);
104 1 : if (!NT_STATUS_IS_OK(status)) {
105 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
106 0 : return false;
107 : }
108 :
109 2 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
110 1 : cli->smb2.tcon, 0x10000, 0, fid_persistent,
111 : fid_volatile, 2, 0,
112 : talloc_tos(), &result, &nread);
113 1 : if (!NT_STATUS_IS_OK(status)) {
114 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
115 0 : return false;
116 : }
117 :
118 1 : if (nread != strlen(hello)) {
119 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
120 0 : (int)nread, (int)strlen(hello));
121 0 : return false;
122 : }
123 :
124 1 : if (memcmp(hello, result, nread) != 0) {
125 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
126 : result, hello);
127 0 : return false;
128 : }
129 :
130 2 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
131 1 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
132 1 : if (!NT_STATUS_IS_OK(status)) {
133 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
134 0 : return false;
135 : }
136 :
137 1 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
138 1 : cli->smb2.tcon, "",
139 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
140 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
141 : SEC_STD_SYNCHRONIZE|
142 : SEC_DIR_LIST|
143 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
144 : 0, /* file_attributes, */
145 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
146 : FILE_OPEN, /* create_disposition, */
147 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
148 : NULL, /* smb2_create_blobs *blobs */
149 : &fid_persistent,
150 : &fid_volatile,
151 : NULL, NULL, NULL);
152 1 : if (!NT_STATUS_IS_OK(status)) {
153 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
154 0 : return false;
155 : }
156 :
157 5 : status = smb2cli_query_directory(
158 4 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
159 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
160 : talloc_tos(), &dir_data, &dir_data_length);
161 :
162 1 : if (!NT_STATUS_IS_OK(status)) {
163 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
164 0 : return false;
165 : }
166 :
167 2 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
168 1 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
169 1 : if (!NT_STATUS_IS_OK(status)) {
170 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
171 0 : return false;
172 : }
173 :
174 1 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
175 1 : saved_tcon = cli_state_save_tcon(cli);
176 1 : if (saved_tcon == NULL) {
177 0 : return false;
178 : }
179 1 : cli->smb2.tcon = smbXcli_tcon_create(cli);
180 1 : smb2cli_tcon_set_values(cli->smb2.tcon,
181 : NULL, /* session */
182 : saved_tid,
183 : 0, /* type */
184 : 0, /* flags */
185 : 0, /* capabilities */
186 : 0 /* maximal_access */);
187 3 : status = smb2cli_tdis(cli->conn,
188 1 : cli->timeout,
189 1 : cli->smb2.session,
190 1 : cli->smb2.tcon);
191 1 : cli_state_restore_tcon(cli, saved_tcon);
192 1 : if (!NT_STATUS_IS_OK(status)) {
193 0 : printf("smb2cli_tdis returned %s\n", nt_errstr(status));
194 0 : return false;
195 : }
196 :
197 3 : status = smb2cli_tdis(cli->conn,
198 1 : cli->timeout,
199 1 : cli->smb2.session,
200 1 : cli->smb2.tcon);
201 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
202 0 : printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
203 0 : return false;
204 : }
205 :
206 1 : saved_uid = smb2cli_session_current_id(cli->smb2.session);
207 1 : status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
208 1 : if (!NT_STATUS_IS_OK(status)) {
209 0 : printf("smb2cli_logoff returned %s\n", nt_errstr(status));
210 0 : return false;
211 : }
212 :
213 1 : cli->smb2.session = smbXcli_session_create(cli, cli->conn);
214 1 : if (cli->smb2.session == NULL) {
215 0 : printf("smbXcli_session_create() returned NULL\n");
216 0 : return false;
217 : }
218 :
219 1 : smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
220 :
221 1 : status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
222 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
223 0 : printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
224 0 : return false;
225 : }
226 :
227 1 : return true;
228 : }
229 :
230 0 : bool run_smb2_negprot(int dummy)
231 : {
232 : struct cli_state *cli;
233 : NTSTATUS status;
234 : enum protocol_types protocol;
235 0 : const char *name = NULL;
236 :
237 0 : printf("Starting SMB2-NEGPROT\n");
238 :
239 0 : if (!torture_init_connection(&cli)) {
240 0 : return false;
241 : }
242 :
243 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
244 : PROTOCOL_CORE, PROTOCOL_LATEST);
245 0 : if (!NT_STATUS_IS_OK(status)) {
246 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
247 0 : return false;
248 : }
249 :
250 0 : protocol = smbXcli_conn_protocol(cli->conn);
251 0 : name = smb_protocol_types_string(protocol);
252 :
253 0 : if (protocol >= PROTOCOL_SMB2_02) {
254 0 : printf("Server supports %s\n", name);
255 : } else {
256 0 : printf("Server DOES NOT support SMB2, only %s\n", name);
257 0 : return false;
258 : }
259 :
260 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
261 : protocol, protocol);
262 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
263 0 : !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
264 0 : !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
265 0 : printf("2nd smbXcli_negprot should disconnect - returned %s\n",
266 : nt_errstr(status));
267 0 : return false;
268 : }
269 :
270 0 : if (smbXcli_conn_is_connected(cli->conn)) {
271 0 : printf("2nd smbXcli_negprot should disconnect "
272 : "- still connected\n");
273 0 : return false;
274 : }
275 :
276 0 : return true;
277 : }
278 :
279 1 : bool run_smb2_anonymous(int dummy)
280 : {
281 1 : struct cli_state *cli = NULL;
282 : NTSTATUS status;
283 1 : struct cli_credentials *anon_creds = NULL;
284 1 : bool guest = false;
285 :
286 1 : printf("Starting SMB2-ANONYMOUS\n");
287 :
288 1 : if (!torture_init_connection(&cli)) {
289 0 : return false;
290 : }
291 :
292 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
293 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
294 1 : if (!NT_STATUS_IS_OK(status)) {
295 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
296 0 : return false;
297 : }
298 :
299 1 : anon_creds = cli_credentials_init_anon(talloc_tos());
300 1 : if (anon_creds == NULL) {
301 0 : printf("cli_credentials_init_anon failed\n");
302 0 : return false;
303 : }
304 :
305 1 : status = cli_session_setup_creds(cli, anon_creds);
306 1 : if (!NT_STATUS_IS_OK(status)) {
307 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
308 0 : return false;
309 : }
310 :
311 1 : guest = smbXcli_session_is_guest(cli->smb2.session);
312 1 : if (guest) {
313 0 : printf("anonymous session should not have guest authentication\n");
314 0 : return false;
315 : }
316 :
317 1 : return true;
318 : }
319 :
320 0 : bool run_smb2_session_reconnect(int dummy)
321 : {
322 : struct cli_state *cli1;
323 : struct cli_state *cli2;
324 : NTSTATUS status;
325 : bool ok;
326 : uint64_t fid_persistent, fid_volatile;
327 : struct tevent_context *ev;
328 : struct tevent_req *subreq;
329 0 : DATA_BLOB in_blob = data_blob_null;
330 : DATA_BLOB out_blob;
331 : DATA_BLOB session_key;
332 : struct auth_generic_state *auth_generic_state;
333 : struct iovec *recv_iov;
334 0 : const char *hello = "Hello, world\n";
335 : uint8_t *result;
336 : uint32_t nread;
337 :
338 0 : printf("Starting SMB2-SESSION-RECONNECT\n");
339 :
340 0 : if (!torture_init_connection(&cli1)) {
341 0 : return false;
342 : }
343 :
344 0 : status = smbXcli_negprot(cli1->conn, cli1->timeout,
345 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
346 0 : if (!NT_STATUS_IS_OK(status)) {
347 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
348 0 : return false;
349 : }
350 :
351 0 : status = cli_session_setup_creds(cli1, torture_creds);
352 0 : if (!NT_STATUS_IS_OK(status)) {
353 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
354 0 : return false;
355 : }
356 :
357 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
358 0 : if (!NT_STATUS_IS_OK(status)) {
359 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
360 0 : return false;
361 : }
362 :
363 0 : status = smb2cli_create(cli1->conn, cli1->timeout, cli1->smb2.session,
364 0 : cli1->smb2.tcon, "session-reconnect.txt",
365 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
366 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
367 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
368 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
369 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
370 : FILE_CREATE, /* create_disposition, */
371 : FILE_DELETE_ON_CLOSE, /* create_options, */
372 : NULL, /* smb2_create_blobs *blobs */
373 : &fid_persistent,
374 : &fid_volatile,
375 : NULL, NULL, NULL);
376 0 : if (!NT_STATUS_IS_OK(status)) {
377 0 : printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
378 0 : return false;
379 : }
380 :
381 0 : status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
382 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
383 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
384 0 : if (!NT_STATUS_IS_OK(status)) {
385 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
386 0 : return false;
387 : }
388 :
389 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
390 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
391 0 : if (!NT_STATUS_IS_OK(status)) {
392 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
393 0 : return false;
394 : }
395 :
396 0 : status = smb2cli_read(cli1->conn, cli1->timeout, cli1->smb2.session,
397 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
398 : fid_volatile, 2, 0,
399 : talloc_tos(), &result, &nread);
400 0 : if (!NT_STATUS_IS_OK(status)) {
401 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
402 0 : return false;
403 : }
404 :
405 0 : if (nread != strlen(hello)) {
406 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
407 0 : (int)nread, (int)strlen(hello));
408 0 : return false;
409 : }
410 :
411 0 : if (memcmp(hello, result, nread) != 0) {
412 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
413 : result, hello);
414 0 : return false;
415 : }
416 :
417 : /* prepare second session */
418 :
419 0 : if (!torture_init_connection(&cli2)) {
420 0 : return false;
421 : }
422 :
423 0 : status = smbXcli_negprot(cli2->conn, cli2->timeout,
424 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
425 0 : if (!NT_STATUS_IS_OK(status)) {
426 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
427 0 : return false;
428 : }
429 :
430 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
431 0 : if (!NT_STATUS_IS_OK(status)) {
432 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
433 0 : return false;
434 : }
435 :
436 0 : gensec_want_feature(auth_generic_state->gensec_security,
437 : GENSEC_FEATURE_SESSION_KEY);
438 :
439 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
440 0 : if (!NT_STATUS_IS_OK(status)) {
441 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
442 0 : return false;
443 : }
444 :
445 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
446 0 : if (!NT_STATUS_IS_OK(status)) {
447 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
448 0 : return false;
449 : }
450 :
451 0 : ev = samba_tevent_context_init(talloc_tos());
452 0 : if (ev == NULL) {
453 0 : printf("samba_tevent_context_init() returned NULL\n");
454 0 : return false;
455 : }
456 :
457 0 : status = gensec_update(auth_generic_state->gensec_security,
458 : talloc_tos(), data_blob_null, &in_blob);
459 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
460 0 : printf("gensec_update returned %s\n", nt_errstr(status));
461 0 : return false;
462 : }
463 :
464 0 : cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
465 :
466 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
467 0 : cli2->conn,
468 0 : cli2->timeout,
469 0 : cli2->smb2.session,
470 : 0x0, /* in_flags */
471 : SMB2_CAP_DFS, /* in_capabilities */
472 : 0, /* in_channel */
473 : /* in_previous_session_id: */
474 0 : smb2cli_session_current_id(cli1->smb2.session),
475 : &in_blob); /* in_security_buffer */
476 0 : if (subreq == NULL) {
477 0 : printf("smb2cli_session_setup_send() returned NULL\n");
478 0 : return false;
479 : }
480 :
481 0 : ok = tevent_req_poll(subreq, ev);
482 0 : if (!ok) {
483 0 : printf("tevent_req_poll() returned false\n");
484 0 : return false;
485 : }
486 :
487 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
488 : NULL, &out_blob);
489 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
490 0 : printf("smb2cli_session_setup_recv returned %s\n",
491 : nt_errstr(status));
492 0 : return false;
493 : }
494 :
495 0 : status = gensec_update(auth_generic_state->gensec_security,
496 : talloc_tos(), out_blob, &in_blob);
497 0 : if (!NT_STATUS_IS_OK(status)) {
498 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
499 0 : return false;
500 : }
501 :
502 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
503 0 : cli2->conn,
504 0 : cli2->timeout,
505 0 : cli2->smb2.session,
506 : 0x0, /* in_flags */
507 : SMB2_CAP_DFS, /* in_capabilities */
508 : 0, /* in_channel */
509 : /* in_previous_session_id: */
510 0 : smb2cli_session_current_id(cli1->smb2.session),
511 : &in_blob); /* in_security_buffer */
512 0 : if (subreq == NULL) {
513 0 : printf("smb2cli_session_setup_send() returned NULL\n");
514 0 : return false;
515 : }
516 :
517 0 : ok = tevent_req_poll(subreq, ev);
518 0 : if (!ok) {
519 0 : printf("tevent_req_poll() returned false\n");
520 0 : return false;
521 : }
522 :
523 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
524 : &recv_iov, &out_blob);
525 0 : if (!NT_STATUS_IS_OK(status)) {
526 0 : printf("smb2cli_session_setup_recv returned %s\n",
527 : nt_errstr(status));
528 0 : return false;
529 : }
530 :
531 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
532 : &session_key);
533 0 : if (!NT_STATUS_IS_OK(status)) {
534 0 : printf("gensec_session_key returned %s\n",
535 : nt_errstr(status));
536 0 : return false;
537 : }
538 :
539 : /* check file operation on the old client */
540 :
541 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
542 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
543 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
544 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
545 0 : return false;
546 : }
547 :
548 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
549 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
550 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
551 0 : return false;
552 : }
553 :
554 : /*
555 : * checking file operations without signing.
556 : * on w2k8r2 at least, flush, read and write also work the same way,
557 : * while create gives ACCESS_DENIED without signing
558 : */
559 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
560 0 : cli2->smb2.tcon, fid_persistent, fid_volatile);
561 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
562 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
563 : {
564 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
565 0 : return false;
566 : }
567 :
568 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
569 0 : cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
570 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
571 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
572 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
573 : {
574 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
575 0 : return false;
576 : }
577 :
578 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
579 0 : cli2->smb2.tcon, 0x10000, 0, fid_persistent,
580 : fid_volatile, 2, 0,
581 : talloc_tos(), &result, &nread);
582 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
583 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
584 : {
585 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
586 0 : return false;
587 : }
588 :
589 0 : status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
590 0 : cli2->smb2.tcon, "session-reconnect.txt",
591 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
592 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
593 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
594 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
595 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
596 : FILE_CREATE, /* create_disposition, */
597 : FILE_DELETE_ON_CLOSE, /* create_options, */
598 : NULL, /* smb2_create_blobs *blobs */
599 : &fid_persistent,
600 : &fid_volatile,
601 : NULL, NULL, NULL);
602 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
603 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
604 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
605 0 : return false;
606 : }
607 :
608 : /* now grab the session key and try with signing */
609 :
610 0 : status = smb2cli_session_set_session_key(cli2->smb2.session,
611 : session_key,
612 : recv_iov);
613 0 : if (!NT_STATUS_IS_OK(status)) {
614 0 : printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
615 0 : return false;
616 : }
617 :
618 : /* the tid seems to be irrelevant at this stage */
619 :
620 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
621 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
622 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
623 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
624 : {
625 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
626 0 : return false;
627 : }
628 :
629 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
630 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
631 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
632 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
633 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
634 : {
635 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
636 0 : return false;
637 : }
638 :
639 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
640 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
641 : fid_volatile, 2, 0,
642 : talloc_tos(), &result, &nread);
643 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
644 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
645 : {
646 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
647 0 : return false;
648 : }
649 :
650 0 : status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
651 0 : cli1->smb2.tcon, "session-reconnect.txt",
652 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
653 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
654 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
655 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
656 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
657 : FILE_CREATE, /* create_disposition, */
658 : FILE_DELETE_ON_CLOSE, /* create_options, */
659 : NULL, /* smb2_create_blobs *blobs */
660 : &fid_persistent,
661 : &fid_volatile,
662 : NULL, NULL, NULL);
663 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) &&
664 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
665 : {
666 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
667 0 : return false;
668 : }
669 :
670 : /* now do a new tcon and test file calls again */
671 :
672 0 : status = cli_tree_connect(cli2, share, "?????", NULL);
673 0 : if (!NT_STATUS_IS_OK(status)) {
674 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
675 0 : return false;
676 : }
677 :
678 0 : status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
679 0 : cli2->smb2.tcon, "session-reconnect.txt",
680 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
681 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
682 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
683 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
684 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
685 : FILE_CREATE, /* create_disposition, */
686 : FILE_DELETE_ON_CLOSE, /* create_options, */
687 : NULL, /* smb2_create_blobs *blobs */
688 : &fid_persistent,
689 : &fid_volatile,
690 : NULL, NULL, NULL);
691 0 : if (!NT_STATUS_IS_OK(status)) {
692 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
693 0 : return false;
694 : }
695 :
696 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
697 0 : cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
698 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
699 0 : if (!NT_STATUS_IS_OK(status)) {
700 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
701 0 : return false;
702 : }
703 :
704 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
705 0 : cli2->smb2.tcon, fid_persistent, fid_volatile);
706 0 : if (!NT_STATUS_IS_OK(status)) {
707 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
708 0 : return false;
709 : }
710 :
711 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
712 0 : cli2->smb2.tcon, 0x10000, 0, fid_persistent,
713 : fid_volatile, 2, 0,
714 : talloc_tos(), &result, &nread);
715 0 : if (!NT_STATUS_IS_OK(status)) {
716 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
717 0 : return false;
718 : }
719 :
720 0 : if (nread != strlen(hello)) {
721 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
722 0 : (int)nread, (int)strlen(hello));
723 0 : return false;
724 : }
725 :
726 0 : if (memcmp(hello, result, nread) != 0) {
727 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
728 : result, hello);
729 0 : return false;
730 : }
731 :
732 0 : return true;
733 : }
734 :
735 0 : bool run_smb2_tcon_dependence(int dummy)
736 : {
737 : struct cli_state *cli;
738 : NTSTATUS status;
739 : uint64_t fid_persistent, fid_volatile;
740 0 : const char *hello = "Hello, world\n";
741 : uint8_t *result;
742 : uint32_t nread;
743 : struct smbXcli_tcon *tcon2;
744 : uint32_t tcon2_id;
745 :
746 0 : printf("Starting SMB2-TCON-DEPENDENCE\n");
747 :
748 0 : if (!torture_init_connection(&cli)) {
749 0 : return false;
750 : }
751 :
752 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
753 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
754 0 : if (!NT_STATUS_IS_OK(status)) {
755 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
756 0 : return false;
757 : }
758 :
759 0 : status = cli_session_setup_creds(cli, torture_creds);
760 0 : if (!NT_STATUS_IS_OK(status)) {
761 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
762 0 : return false;
763 : }
764 :
765 0 : status = cli_tree_connect(cli, share, "?????", NULL);
766 0 : if (!NT_STATUS_IS_OK(status)) {
767 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
768 0 : return false;
769 : }
770 :
771 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
772 0 : cli->smb2.tcon, "tcon_depedence.txt",
773 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
774 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
775 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
776 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
777 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
778 : FILE_CREATE, /* create_disposition, */
779 : FILE_DELETE_ON_CLOSE, /* create_options, */
780 : NULL, /* smb2_create_blobs *blobs */
781 : &fid_persistent,
782 : &fid_volatile,
783 : NULL, NULL, NULL);
784 0 : if (!NT_STATUS_IS_OK(status)) {
785 0 : printf("smb2cli_create on cli %s\n", nt_errstr(status));
786 0 : return false;
787 : }
788 :
789 0 : status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
790 0 : cli->smb2.tcon, strlen(hello), 0, fid_persistent,
791 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
792 0 : if (!NT_STATUS_IS_OK(status)) {
793 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
794 0 : return false;
795 : }
796 :
797 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
798 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
799 0 : if (!NT_STATUS_IS_OK(status)) {
800 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
801 0 : return false;
802 : }
803 :
804 0 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
805 0 : cli->smb2.tcon, 0x10000, 0, fid_persistent,
806 : fid_volatile, 2, 0,
807 : talloc_tos(), &result, &nread);
808 0 : if (!NT_STATUS_IS_OK(status)) {
809 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
810 0 : return false;
811 : }
812 :
813 0 : if (nread != strlen(hello)) {
814 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
815 0 : (int)nread, (int)strlen(hello));
816 0 : return false;
817 : }
818 :
819 0 : if (memcmp(hello, result, nread) != 0) {
820 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
821 : result, hello);
822 0 : return false;
823 : }
824 :
825 : /* check behaviour with wrong tid... */
826 :
827 0 : tcon2 = smbXcli_tcon_create(cli);
828 0 : tcon2_id = smb2cli_tcon_current_id(cli->smb2.tcon);
829 0 : tcon2_id++;
830 0 : smb2cli_tcon_set_values(tcon2,
831 : NULL, /* session */
832 : tcon2_id,
833 : 0, /* type */
834 : 0, /* flags */
835 : 0, /* capabilities */
836 : 0 /* maximal_access */);
837 :
838 0 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
839 : tcon2, 0x10000, 0, fid_persistent,
840 : fid_volatile, 2, 0,
841 : talloc_tos(), &result, &nread);
842 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
843 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
844 0 : return false;
845 : }
846 :
847 0 : talloc_free(tcon2);
848 :
849 0 : return true;
850 : }
851 :
852 0 : bool run_smb2_multi_channel(int dummy)
853 : {
854 : struct cli_state *cli1;
855 : struct cli_state *cli2;
856 : struct cli_state *cli3;
857 : NTSTATUS status;
858 : bool ok;
859 : uint64_t fid_persistent, fid_volatile;
860 : struct tevent_context *ev;
861 : struct tevent_req *subreq;
862 0 : DATA_BLOB in_blob = data_blob_null;
863 : DATA_BLOB out_blob;
864 : DATA_BLOB channel_session_key;
865 : struct auth_generic_state *auth_generic_state;
866 : struct iovec *recv_iov;
867 0 : const char *hello = "Hello, world\n";
868 : uint8_t *result;
869 : uint32_t nread;
870 0 : struct GUID saved_guid = cli_state_client_guid;
871 :
872 0 : printf("Starting SMB2-MULTI-CHANNEL\n");
873 :
874 0 : cli_state_client_guid = GUID_random();
875 :
876 0 : if (!torture_init_connection(&cli1)) {
877 0 : return false;
878 : }
879 :
880 0 : if (!torture_init_connection(&cli2)) {
881 0 : return false;
882 : }
883 :
884 0 : if (!torture_init_connection(&cli3)) {
885 0 : return false;
886 : }
887 :
888 0 : cli_state_client_guid = saved_guid;
889 :
890 0 : status = smbXcli_negprot(cli1->conn, cli1->timeout,
891 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
892 0 : if (!NT_STATUS_IS_OK(status)) {
893 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
894 0 : return false;
895 : }
896 :
897 0 : status = smbXcli_negprot(cli2->conn, cli2->timeout,
898 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
899 0 : if (!NT_STATUS_IS_OK(status)) {
900 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
901 0 : return false;
902 : }
903 :
904 0 : status = smbXcli_negprot(cli3->conn, cli3->timeout,
905 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
906 0 : if (!NT_STATUS_IS_OK(status)) {
907 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
908 0 : return false;
909 : }
910 :
911 0 : status = cli_session_setup_creds(cli1, torture_creds);
912 0 : if (!NT_STATUS_IS_OK(status)) {
913 0 : printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
914 0 : return false;
915 : }
916 :
917 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
918 0 : if (!NT_STATUS_IS_OK(status)) {
919 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
920 0 : return false;
921 : }
922 :
923 0 : status = smb2cli_session_create_channel(cli2,
924 0 : cli1->smb2.session,
925 0 : cli2->conn,
926 0 : &cli2->smb2.session);
927 0 : if (!NT_STATUS_IS_OK(status)) {
928 0 : printf("smb2cli_session_create_channel returned %s\n",
929 : nt_errstr(status));
930 0 : return false;
931 : }
932 :
933 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
934 0 : if (!NT_STATUS_IS_OK(status)) {
935 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
936 0 : return false;
937 : }
938 :
939 0 : gensec_want_feature(auth_generic_state->gensec_security,
940 : GENSEC_FEATURE_SESSION_KEY);
941 :
942 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
943 0 : if (!NT_STATUS_IS_OK(status)) {
944 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
945 0 : return false;
946 : }
947 :
948 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
949 0 : if (!NT_STATUS_IS_OK(status)) {
950 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
951 0 : return false;
952 : }
953 :
954 0 : ev = samba_tevent_context_init(talloc_tos());
955 0 : if (ev == NULL) {
956 0 : printf("samba_tevent_context_init() returned NULL\n");
957 0 : return false;
958 : }
959 :
960 0 : status = gensec_update(auth_generic_state->gensec_security,
961 : talloc_tos(), data_blob_null, &in_blob);
962 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
963 0 : printf("gensec_update returned %s\n", nt_errstr(status));
964 0 : return false;
965 : }
966 :
967 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
968 0 : cli2->conn,
969 0 : cli2->timeout,
970 0 : cli2->smb2.session,
971 : 0x01, /* in_flags */
972 : SMB2_CAP_DFS, /* in_capabilities */
973 : 0, /* in_channel */
974 : 0, /* in_previous_session_id */
975 : &in_blob); /* in_security_buffer */
976 0 : if (subreq == NULL) {
977 0 : printf("smb2cli_session_setup_send() returned NULL\n");
978 0 : return false;
979 : }
980 :
981 0 : ok = tevent_req_poll(subreq, ev);
982 0 : if (!ok) {
983 0 : printf("tevent_req_poll() returned false\n");
984 0 : return false;
985 : }
986 :
987 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
988 : NULL, &out_blob);
989 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
990 0 : printf("smb2cli_session_setup_recv returned %s\n",
991 : nt_errstr(status));
992 0 : return false;
993 : }
994 :
995 0 : status = gensec_update(auth_generic_state->gensec_security,
996 : talloc_tos(), out_blob, &in_blob);
997 0 : if (!NT_STATUS_IS_OK(status)) {
998 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
999 0 : return false;
1000 : }
1001 :
1002 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1003 0 : cli2->conn,
1004 0 : cli2->timeout,
1005 0 : cli2->smb2.session,
1006 : 0x01, /* in_flags */
1007 : SMB2_CAP_DFS, /* in_capabilities */
1008 : 0, /* in_channel */
1009 : 0, /* in_previous_session_id */
1010 : &in_blob); /* in_security_buffer */
1011 0 : if (subreq == NULL) {
1012 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1013 0 : return false;
1014 : }
1015 :
1016 0 : ok = tevent_req_poll(subreq, ev);
1017 0 : if (!ok) {
1018 0 : printf("tevent_req_poll() returned false\n");
1019 0 : return false;
1020 : }
1021 :
1022 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1023 : &recv_iov, &out_blob);
1024 0 : if (!NT_STATUS_IS_OK(status)) {
1025 0 : printf("smb2cli_session_setup_recv returned %s\n",
1026 : nt_errstr(status));
1027 0 : return false;
1028 : }
1029 :
1030 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1031 : &channel_session_key);
1032 0 : if (!NT_STATUS_IS_OK(status)) {
1033 0 : printf("gensec_session_key returned %s\n",
1034 : nt_errstr(status));
1035 0 : return false;
1036 : }
1037 :
1038 0 : status = smb2cli_session_set_channel_key(cli2->smb2.session,
1039 : channel_session_key,
1040 : recv_iov);
1041 0 : if (!NT_STATUS_IS_OK(status)) {
1042 0 : printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1043 0 : return false;
1044 : }
1045 :
1046 0 : status = smb2cli_session_create_channel(cli3,
1047 0 : cli1->smb2.session,
1048 0 : cli3->conn,
1049 0 : &cli3->smb2.session);
1050 0 : if (!NT_STATUS_IS_OK(status)) {
1051 0 : printf("smb2cli_session_create_channel returned %s\n",
1052 : nt_errstr(status));
1053 0 : return false;
1054 : }
1055 :
1056 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1057 0 : if (!NT_STATUS_IS_OK(status)) {
1058 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1059 0 : return false;
1060 : }
1061 :
1062 0 : gensec_want_feature(auth_generic_state->gensec_security,
1063 : GENSEC_FEATURE_SESSION_KEY);
1064 :
1065 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1066 0 : if (!NT_STATUS_IS_OK(status)) {
1067 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1068 0 : return false;
1069 : }
1070 :
1071 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1072 0 : if (!NT_STATUS_IS_OK(status)) {
1073 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1074 0 : return false;
1075 : }
1076 :
1077 0 : status = gensec_update(auth_generic_state->gensec_security,
1078 : talloc_tos(), data_blob_null, &in_blob);
1079 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1080 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1081 0 : return false;
1082 : }
1083 :
1084 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1085 0 : cli3->conn,
1086 0 : cli3->timeout,
1087 0 : cli3->smb2.session,
1088 : 0x01, /* in_flags */
1089 : SMB2_CAP_DFS, /* in_capabilities */
1090 : 0, /* in_channel */
1091 : 0, /* in_previous_session_id */
1092 : &in_blob); /* in_security_buffer */
1093 0 : if (subreq == NULL) {
1094 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1095 0 : return false;
1096 : }
1097 :
1098 0 : ok = tevent_req_poll(subreq, ev);
1099 0 : if (!ok) {
1100 0 : printf("tevent_req_poll() returned false\n");
1101 0 : return false;
1102 : }
1103 :
1104 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1105 : NULL, &out_blob);
1106 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1107 0 : printf("smb2cli_session_setup_recv returned %s\n",
1108 : nt_errstr(status));
1109 0 : return false;
1110 : }
1111 :
1112 0 : status = gensec_update(auth_generic_state->gensec_security,
1113 : talloc_tos(), out_blob, &in_blob);
1114 0 : if (!NT_STATUS_IS_OK(status)) {
1115 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1116 0 : return false;
1117 : }
1118 :
1119 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1120 0 : cli3->conn,
1121 0 : cli3->timeout,
1122 0 : cli3->smb2.session,
1123 : 0x01, /* in_flags */
1124 : SMB2_CAP_DFS, /* in_capabilities */
1125 : 0, /* in_channel */
1126 : 0, /* in_previous_session_id */
1127 : &in_blob); /* in_security_buffer */
1128 0 : if (subreq == NULL) {
1129 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1130 0 : return false;
1131 : }
1132 :
1133 0 : ok = tevent_req_poll(subreq, ev);
1134 0 : if (!ok) {
1135 0 : printf("tevent_req_poll() returned false\n");
1136 0 : return false;
1137 : }
1138 :
1139 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1140 : &recv_iov, &out_blob);
1141 0 : if (!NT_STATUS_IS_OK(status)) {
1142 0 : printf("smb2cli_session_setup_recv returned %s\n",
1143 : nt_errstr(status));
1144 0 : return false;
1145 : }
1146 :
1147 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1148 : &channel_session_key);
1149 0 : if (!NT_STATUS_IS_OK(status)) {
1150 0 : printf("gensec_session_key returned %s\n",
1151 : nt_errstr(status));
1152 0 : return false;
1153 : }
1154 :
1155 0 : status = smb2cli_session_set_channel_key(cli3->smb2.session,
1156 : channel_session_key,
1157 : recv_iov);
1158 0 : if (!NT_STATUS_IS_OK(status)) {
1159 0 : printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1160 0 : return false;
1161 : }
1162 :
1163 0 : status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
1164 0 : cli1->smb2.tcon, "multi-channel.txt",
1165 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1166 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1167 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1168 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1169 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1170 : FILE_CREATE, /* create_disposition, */
1171 : FILE_DELETE_ON_CLOSE, /* create_options, */
1172 : NULL, /* smb2_create_blobs *blobs */
1173 : &fid_persistent,
1174 : &fid_volatile,
1175 : NULL, NULL, NULL);
1176 0 : if (!NT_STATUS_IS_OK(status)) {
1177 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
1178 0 : return false;
1179 : }
1180 :
1181 0 : status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
1182 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
1183 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
1184 0 : if (!NT_STATUS_IS_OK(status)) {
1185 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
1186 0 : return false;
1187 : }
1188 :
1189 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1190 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1191 0 : if (!NT_STATUS_IS_OK(status)) {
1192 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1193 0 : return false;
1194 : }
1195 :
1196 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1197 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1198 0 : if (!NT_STATUS_IS_OK(status)) {
1199 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1200 0 : return false;
1201 : }
1202 :
1203 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1204 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1205 0 : if (!NT_STATUS_IS_OK(status)) {
1206 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1207 0 : return false;
1208 : }
1209 :
1210 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
1211 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
1212 : fid_volatile, 2, 0,
1213 : talloc_tos(), &result, &nread);
1214 0 : if (!NT_STATUS_IS_OK(status)) {
1215 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
1216 0 : return false;
1217 : }
1218 :
1219 0 : if (nread != strlen(hello)) {
1220 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
1221 0 : (int)nread, (int)strlen(hello));
1222 0 : return false;
1223 : }
1224 :
1225 0 : if (memcmp(hello, result, nread) != 0) {
1226 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
1227 : result, hello);
1228 0 : return false;
1229 : }
1230 :
1231 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1232 0 : if (!NT_STATUS_IS_OK(status)) {
1233 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1234 0 : return false;
1235 : }
1236 :
1237 0 : gensec_want_feature(auth_generic_state->gensec_security,
1238 : GENSEC_FEATURE_SESSION_KEY);
1239 :
1240 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1241 0 : if (!NT_STATUS_IS_OK(status)) {
1242 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1243 0 : return false;
1244 : }
1245 :
1246 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1247 0 : if (!NT_STATUS_IS_OK(status)) {
1248 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1249 0 : return false;
1250 : }
1251 :
1252 0 : status = gensec_update(auth_generic_state->gensec_security,
1253 : talloc_tos(), data_blob_null, &in_blob);
1254 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1255 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1256 0 : return false;
1257 : }
1258 :
1259 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1260 0 : cli3->conn,
1261 0 : cli3->timeout,
1262 0 : cli3->smb2.session,
1263 : 0x0, /* in_flags */
1264 : SMB2_CAP_DFS, /* in_capabilities */
1265 : 0, /* in_channel */
1266 : 0, /* in_previous_session_id */
1267 : &in_blob); /* in_security_buffer */
1268 0 : if (subreq == NULL) {
1269 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1270 0 : return false;
1271 : }
1272 :
1273 0 : ok = tevent_req_poll(subreq, ev);
1274 0 : if (!ok) {
1275 0 : printf("tevent_req_poll() returned false\n");
1276 0 : return false;
1277 : }
1278 :
1279 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1280 : NULL, &out_blob);
1281 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1282 0 : printf("smb2cli_session_setup_recv returned %s\n",
1283 : nt_errstr(status));
1284 0 : return false;
1285 : }
1286 :
1287 0 : status = gensec_update(auth_generic_state->gensec_security,
1288 : talloc_tos(), out_blob, &in_blob);
1289 0 : if (!NT_STATUS_IS_OK(status)) {
1290 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1291 0 : return false;
1292 : }
1293 :
1294 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1295 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1296 0 : if (!NT_STATUS_IS_OK(status)) {
1297 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1298 0 : return false;
1299 : }
1300 :
1301 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1302 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1303 0 : if (!NT_STATUS_IS_OK(status)) {
1304 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1305 0 : return false;
1306 : }
1307 :
1308 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1309 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1310 0 : if (!NT_STATUS_IS_OK(status)) {
1311 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1312 0 : return false;
1313 : }
1314 :
1315 0 : status = smb2cli_create(cli1->conn, cli1->timeout, cli1->smb2.session,
1316 0 : cli1->smb2.tcon, "multi-channel-invalid.txt",
1317 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1318 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1319 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1320 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1321 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1322 : FILE_CREATE, /* create_disposition, */
1323 : FILE_DELETE_ON_CLOSE, /* create_options, */
1324 : NULL, /* smb2_create_blobs *blobs */
1325 : &fid_persistent,
1326 : &fid_volatile,
1327 : NULL, NULL, NULL);
1328 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1329 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1330 0 : return false;
1331 : }
1332 :
1333 0 : status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
1334 0 : cli1->smb2.tcon, "multi-channel-invalid.txt",
1335 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1336 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1337 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1338 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1339 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1340 : FILE_CREATE, /* create_disposition, */
1341 : FILE_DELETE_ON_CLOSE, /* create_options, */
1342 : NULL, /* smb2_create_blobs *blobs */
1343 : &fid_persistent,
1344 : &fid_volatile,
1345 : NULL, NULL, NULL);
1346 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1347 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1348 0 : return false;
1349 : }
1350 :
1351 0 : status = smb2cli_create(cli3->conn, cli3->timeout, cli3->smb2.session,
1352 0 : cli1->smb2.tcon, "multi-channel-invalid.txt",
1353 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1354 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1355 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1356 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1357 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1358 : FILE_CREATE, /* create_disposition, */
1359 : FILE_DELETE_ON_CLOSE, /* create_options, */
1360 : NULL, /* smb2_create_blobs *blobs */
1361 : &fid_persistent,
1362 : &fid_volatile,
1363 : NULL, NULL, NULL);
1364 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1365 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1366 0 : return false;
1367 : }
1368 :
1369 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1370 0 : cli2->conn,
1371 0 : cli2->timeout,
1372 0 : cli2->smb2.session,
1373 : 0x0, /* in_flags */
1374 : SMB2_CAP_DFS, /* in_capabilities */
1375 : 0, /* in_channel */
1376 : 0, /* in_previous_session_id */
1377 : &in_blob); /* in_security_buffer */
1378 0 : if (subreq == NULL) {
1379 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1380 0 : return false;
1381 : }
1382 :
1383 0 : ok = tevent_req_poll(subreq, ev);
1384 0 : if (!ok) {
1385 0 : printf("tevent_req_poll() returned false\n");
1386 0 : return false;
1387 : }
1388 :
1389 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1390 : &recv_iov, &out_blob);
1391 0 : if (!NT_STATUS_IS_OK(status)) {
1392 0 : printf("smb2cli_session_setup_recv returned %s\n",
1393 : nt_errstr(status));
1394 0 : return false;
1395 : }
1396 :
1397 0 : status = smb2cli_close(cli3->conn, cli3->timeout, cli3->smb2.session,
1398 0 : cli1->smb2.tcon, 0, fid_persistent, fid_volatile);
1399 0 : if (!NT_STATUS_IS_OK(status)) {
1400 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1401 0 : return false;
1402 : }
1403 :
1404 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1405 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1406 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1407 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1408 0 : return false;
1409 : }
1410 :
1411 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1412 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1413 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1414 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1415 0 : return false;
1416 : }
1417 :
1418 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1419 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1420 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1421 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1422 0 : return false;
1423 : }
1424 :
1425 0 : return true;
1426 : }
1427 :
1428 0 : bool run_smb2_session_reauth(int dummy)
1429 : {
1430 : struct cli_state *cli;
1431 : NTSTATUS status;
1432 : bool ok;
1433 : uint64_t fid_persistent, fid_volatile;
1434 : uint64_t dir_persistent, dir_volatile;
1435 : uint8_t *dir_data;
1436 : uint32_t dir_data_length;
1437 : struct tevent_context *ev;
1438 : struct tevent_req *subreq;
1439 0 : DATA_BLOB in_blob = data_blob_null;
1440 : DATA_BLOB out_blob;
1441 : DATA_BLOB in_input_buffer;
1442 : DATA_BLOB out_output_buffer;
1443 : uint8_t in_file_info_class;
1444 : struct auth_generic_state *auth_generic_state;
1445 : struct iovec *recv_iov;
1446 : uint32_t saved_tid;
1447 : struct smbXcli_tcon *saved_tcon;
1448 :
1449 0 : printf("Starting SMB2-SESSION_REAUTH\n");
1450 :
1451 0 : if (!torture_init_connection(&cli)) {
1452 0 : return false;
1453 : }
1454 :
1455 : /*
1456 : * PROTOCOL_SMB2_22 has a bug in win8pre0
1457 : * it behaves like PROTOCOL_SMB2_02
1458 : * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1459 : * while it allows it on PROTOCOL_SMB2_10.
1460 : */
1461 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
1462 : PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1463 0 : if (!NT_STATUS_IS_OK(status)) {
1464 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1465 0 : return false;
1466 : }
1467 :
1468 0 : status = cli_session_setup_creds(cli, torture_creds);
1469 0 : if (!NT_STATUS_IS_OK(status)) {
1470 0 : printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1471 0 : return false;
1472 : }
1473 :
1474 0 : status = cli_tree_connect(cli, share, "?????", NULL);
1475 0 : if (!NT_STATUS_IS_OK(status)) {
1476 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1477 0 : return false;
1478 : }
1479 :
1480 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1481 0 : cli->smb2.tcon, "session-reauth.txt",
1482 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1483 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1484 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1485 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1486 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1487 : FILE_CREATE, /* create_disposition, */
1488 : FILE_DELETE_ON_CLOSE, /* create_options, */
1489 : NULL, /* smb2_create_blobs *blobs */
1490 : &fid_persistent,
1491 : &fid_volatile,
1492 : NULL, NULL, NULL);
1493 0 : if (!NT_STATUS_IS_OK(status)) {
1494 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1495 0 : return false;
1496 : }
1497 :
1498 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1499 0 : cli->smb2.tcon, "",
1500 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1501 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1502 : SEC_STD_SYNCHRONIZE|
1503 : SEC_DIR_LIST|
1504 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1505 : 0, /* file_attributes, */
1506 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1507 : FILE_OPEN, /* create_disposition, */
1508 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1509 : NULL, /* smb2_create_blobs *blobs */
1510 : &dir_persistent,
1511 : &dir_volatile,
1512 : NULL, NULL, NULL);
1513 0 : if (!NT_STATUS_IS_OK(status)) {
1514 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
1515 0 : return false;
1516 : }
1517 :
1518 0 : status = smb2cli_query_directory(
1519 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1520 : 1, 0x3, 0, dir_persistent, dir_volatile,
1521 : "session-reauth.txt", 0xffff,
1522 : talloc_tos(), &dir_data, &dir_data_length);
1523 0 : if (!NT_STATUS_IS_OK(status)) {
1524 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1525 0 : return false;
1526 : }
1527 :
1528 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1529 0 : if (!NT_STATUS_IS_OK(status)) {
1530 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1531 0 : return false;
1532 : }
1533 :
1534 0 : gensec_want_feature(auth_generic_state->gensec_security,
1535 : GENSEC_FEATURE_SESSION_KEY);
1536 :
1537 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1538 0 : if (!NT_STATUS_IS_OK(status)) {
1539 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1540 0 : return false;
1541 : }
1542 :
1543 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1544 0 : if (!NT_STATUS_IS_OK(status)) {
1545 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1546 0 : return false;
1547 : }
1548 :
1549 0 : ev = samba_tevent_context_init(talloc_tos());
1550 0 : if (ev == NULL) {
1551 0 : printf("samba_tevent_context_init() returned NULL\n");
1552 0 : return false;
1553 : }
1554 :
1555 0 : status = gensec_update(auth_generic_state->gensec_security,
1556 : talloc_tos(), data_blob_null, &in_blob);
1557 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1558 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1559 0 : return false;
1560 : }
1561 :
1562 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1563 0 : cli->conn,
1564 0 : cli->timeout,
1565 0 : cli->smb2.session,
1566 : 0x0, /* in_flags */
1567 : SMB2_CAP_DFS, /* in_capabilities */
1568 : 0, /* in_channel */
1569 : 0, /* in_previous_session_id */
1570 : &in_blob); /* in_security_buffer */
1571 0 : if (subreq == NULL) {
1572 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1573 0 : return false;
1574 : }
1575 :
1576 0 : ok = tevent_req_poll(subreq, ev);
1577 0 : if (!ok) {
1578 0 : printf("tevent_req_poll() returned false\n");
1579 0 : return false;
1580 : }
1581 :
1582 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1583 : NULL, &out_blob);
1584 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1585 0 : printf("smb2cli_session_setup_recv returned %s\n",
1586 : nt_errstr(status));
1587 0 : return false;
1588 : }
1589 :
1590 0 : status = gensec_update(auth_generic_state->gensec_security,
1591 : talloc_tos(), out_blob, &in_blob);
1592 0 : if (!NT_STATUS_IS_OK(status)) {
1593 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1594 0 : return false;
1595 : }
1596 :
1597 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1598 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
1599 0 : if (!NT_STATUS_IS_OK(status)) {
1600 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1601 0 : return false;
1602 : }
1603 :
1604 0 : status = smb2cli_query_directory(
1605 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1606 : 1, 0x3, 0, dir_persistent, dir_volatile,
1607 : "session-reauth.txt", 0xffff,
1608 : talloc_tos(), &dir_data, &dir_data_length);
1609 0 : if (!NT_STATUS_IS_OK(status)) {
1610 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1611 0 : return false;
1612 : }
1613 :
1614 : /*
1615 : * query_info seems to be a path based operation on Windows...
1616 : */
1617 0 : status = smb2cli_query_info(cli->conn,
1618 0 : cli->timeout,
1619 0 : cli->smb2.session,
1620 0 : cli->smb2.tcon,
1621 : SMB2_0_INFO_SECURITY,
1622 : 0, /* in_file_info_class */
1623 : 1024, /* in_max_output_length */
1624 : NULL, /* in_input_buffer */
1625 : SECINFO_OWNER, /* in_additional_info */
1626 : 0, /* in_flags */
1627 : fid_persistent,
1628 : fid_volatile,
1629 : talloc_tos(),
1630 : &out_output_buffer);
1631 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1632 0 : printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1633 0 : return false;
1634 : }
1635 :
1636 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1637 0 : status = smb2cli_query_info(cli->conn,
1638 0 : cli->timeout,
1639 0 : cli->smb2.session,
1640 0 : cli->smb2.tcon,
1641 : SMB2_0_INFO_FILE,
1642 : in_file_info_class,
1643 : 1024, /* in_max_output_length */
1644 : NULL, /* in_input_buffer */
1645 : 0, /* in_additional_info */
1646 : 0, /* in_flags */
1647 : fid_persistent,
1648 : fid_volatile,
1649 : talloc_tos(),
1650 : &out_output_buffer);
1651 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1652 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1653 0 : return false;
1654 : }
1655 :
1656 0 : in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1657 0 : SBVAL(in_input_buffer.data, 0, 512);
1658 :
1659 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1660 0 : status = smb2cli_set_info(cli->conn,
1661 0 : cli->timeout,
1662 0 : cli->smb2.session,
1663 0 : cli->smb2.tcon,
1664 : SMB2_0_INFO_FILE,
1665 : in_file_info_class,
1666 : &in_input_buffer,
1667 : 0, /* in_additional_info */
1668 : fid_persistent,
1669 : fid_volatile);
1670 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1671 0 : printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1672 0 : return false;
1673 : }
1674 :
1675 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1676 0 : cli->smb2.tcon, "session-reauth-invalid.txt",
1677 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1678 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1679 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1680 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1681 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1682 : FILE_CREATE, /* create_disposition, */
1683 : FILE_DELETE_ON_CLOSE, /* create_options, */
1684 : NULL, /* smb2_create_blobs *blobs */
1685 : &fid_persistent,
1686 : &fid_volatile,
1687 : NULL, NULL, NULL);
1688 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1689 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1690 0 : return false;
1691 : }
1692 :
1693 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1694 0 : cli->smb2.tcon, "",
1695 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1696 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1697 : SEC_STD_SYNCHRONIZE|
1698 : SEC_DIR_LIST|
1699 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1700 : 0, /* file_attributes, */
1701 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1702 : FILE_OPEN, /* create_disposition, */
1703 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1704 : NULL, /* smb2_create_blobs *blobs */
1705 : &dir_persistent,
1706 : &dir_volatile,
1707 : NULL, NULL, NULL);
1708 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1709 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
1710 0 : return false;
1711 : }
1712 :
1713 0 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1714 0 : saved_tcon = cli->smb2.tcon;
1715 0 : cli->smb2.tcon = smbXcli_tcon_create(cli);
1716 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
1717 : NULL, /* session */
1718 : saved_tid,
1719 : 0, /* type */
1720 : 0, /* flags */
1721 : 0, /* capabilities */
1722 : 0 /* maximal_access */);
1723 0 : status = cli_tree_connect(cli, share, "?????", NULL);
1724 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1725 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1726 0 : return false;
1727 : }
1728 0 : talloc_free(cli->smb2.tcon);
1729 0 : cli->smb2.tcon = saved_tcon;
1730 :
1731 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1732 0 : cli->conn,
1733 0 : cli->timeout,
1734 0 : cli->smb2.session,
1735 : 0x0, /* in_flags */
1736 : SMB2_CAP_DFS, /* in_capabilities */
1737 : 0, /* in_channel */
1738 : 0, /* in_previous_session_id */
1739 : &in_blob); /* in_security_buffer */
1740 0 : if (subreq == NULL) {
1741 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1742 0 : return false;
1743 : }
1744 :
1745 0 : ok = tevent_req_poll(subreq, ev);
1746 0 : if (!ok) {
1747 0 : printf("tevent_req_poll() returned false\n");
1748 0 : return false;
1749 : }
1750 :
1751 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1752 : &recv_iov, &out_blob);
1753 0 : if (!NT_STATUS_IS_OK(status)) {
1754 0 : printf("smb2cli_session_setup_recv returned %s\n",
1755 : nt_errstr(status));
1756 0 : return false;
1757 : }
1758 :
1759 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1760 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
1761 0 : if (!NT_STATUS_IS_OK(status)) {
1762 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1763 0 : return false;
1764 : }
1765 :
1766 0 : status = smb2cli_query_info(cli->conn,
1767 0 : cli->timeout,
1768 0 : cli->smb2.session,
1769 0 : cli->smb2.tcon,
1770 : SMB2_0_INFO_SECURITY,
1771 : 0, /* in_file_info_class */
1772 : 1024, /* in_max_output_length */
1773 : NULL, /* in_input_buffer */
1774 : SECINFO_OWNER, /* in_additional_info */
1775 : 0, /* in_flags */
1776 : fid_persistent,
1777 : fid_volatile,
1778 : talloc_tos(),
1779 : &out_output_buffer);
1780 0 : if (!NT_STATUS_IS_OK(status)) {
1781 0 : printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1782 0 : return false;
1783 : }
1784 :
1785 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1786 0 : status = smb2cli_query_info(cli->conn,
1787 0 : cli->timeout,
1788 0 : cli->smb2.session,
1789 0 : cli->smb2.tcon,
1790 : SMB2_0_INFO_FILE,
1791 : in_file_info_class,
1792 : 1024, /* in_max_output_length */
1793 : NULL, /* in_input_buffer */
1794 : 0, /* in_additional_info */
1795 : 0, /* in_flags */
1796 : fid_persistent,
1797 : fid_volatile,
1798 : talloc_tos(),
1799 : &out_output_buffer);
1800 0 : if (!NT_STATUS_IS_OK(status)) {
1801 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1802 0 : return false;
1803 : }
1804 :
1805 0 : in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1806 0 : SBVAL(in_input_buffer.data, 0, 512);
1807 :
1808 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1809 0 : status = smb2cli_set_info(cli->conn,
1810 0 : cli->timeout,
1811 0 : cli->smb2.session,
1812 0 : cli->smb2.tcon,
1813 : SMB2_0_INFO_FILE,
1814 : in_file_info_class,
1815 : &in_input_buffer,
1816 : 0, /* in_additional_info */
1817 : fid_persistent,
1818 : fid_volatile);
1819 0 : if (!NT_STATUS_IS_OK(status)) {
1820 0 : printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1821 0 : return false;
1822 : }
1823 :
1824 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1825 0 : status = smb2cli_query_info(cli->conn,
1826 0 : cli->timeout,
1827 0 : cli->smb2.session,
1828 0 : cli->smb2.tcon,
1829 : SMB2_0_INFO_FILE,
1830 : in_file_info_class,
1831 : 1024, /* in_max_output_length */
1832 : NULL, /* in_input_buffer */
1833 : 0, /* in_additional_info */
1834 : 0, /* in_flags */
1835 : fid_persistent,
1836 : fid_volatile,
1837 : talloc_tos(),
1838 : &out_output_buffer);
1839 0 : if (!NT_STATUS_IS_OK(status)) {
1840 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1841 0 : return false;
1842 : }
1843 :
1844 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1845 0 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1846 0 : if (!NT_STATUS_IS_OK(status)) {
1847 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1848 0 : return false;
1849 : }
1850 :
1851 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1852 0 : cli->smb2.tcon, "session-reauth.txt",
1853 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1854 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1855 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1856 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1857 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1858 : FILE_CREATE, /* create_disposition, */
1859 : FILE_DELETE_ON_CLOSE, /* create_options, */
1860 : NULL, /* smb2_create_blobs *blobs */
1861 : &fid_persistent,
1862 : &fid_volatile,
1863 : NULL, NULL, NULL);
1864 0 : if (!NT_STATUS_IS_OK(status)) {
1865 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1866 0 : return false;
1867 : }
1868 :
1869 0 : status = smb2cli_query_directory(
1870 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1871 : 1, 0x3, 0, dir_persistent, dir_volatile,
1872 : "session-reauth.txt", 0xffff,
1873 : talloc_tos(), &dir_data, &dir_data_length);
1874 0 : if (!NT_STATUS_IS_OK(status)) {
1875 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1876 0 : return false;
1877 : }
1878 :
1879 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1880 0 : cli->smb2.tcon, 0, dir_persistent, dir_volatile);
1881 0 : if (!NT_STATUS_IS_OK(status)) {
1882 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1883 0 : return false;
1884 : }
1885 :
1886 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1887 0 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1888 0 : if (!NT_STATUS_IS_OK(status)) {
1889 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1890 0 : return false;
1891 : }
1892 :
1893 0 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1894 0 : saved_tcon = cli->smb2.tcon;
1895 0 : cli->smb2.tcon = smbXcli_tcon_create(cli);
1896 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
1897 : NULL, /* session */
1898 : saved_tid,
1899 : 0, /* type */
1900 : 0, /* flags */
1901 : 0, /* capabilities */
1902 : 0 /* maximal_access */);
1903 0 : status = cli_tree_connect(cli, share, "?????", NULL);
1904 0 : if (!NT_STATUS_IS_OK(status)) {
1905 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1906 0 : return false;
1907 : }
1908 0 : talloc_free(cli->smb2.tcon);
1909 0 : cli->smb2.tcon = saved_tcon;
1910 :
1911 0 : return true;
1912 : }
1913 :
1914 11 : static NTSTATUS check_size(struct cli_state *cli,
1915 : uint16_t fnum,
1916 : const char *fname,
1917 : size_t size)
1918 : {
1919 11 : off_t size_read = 0;
1920 :
1921 11 : NTSTATUS status = cli_qfileinfo_basic(cli,
1922 : fnum,
1923 : NULL,
1924 : &size_read,
1925 : NULL,
1926 : NULL,
1927 : NULL,
1928 : NULL,
1929 : NULL);
1930 :
1931 11 : if (!NT_STATUS_IS_OK(status)) {
1932 0 : printf("cli_qfileinfo_basic of %s failed (%s)\n",
1933 : fname,
1934 : nt_errstr(status));
1935 0 : return status;
1936 : }
1937 :
1938 11 : if (size != size_read) {
1939 0 : printf("size (%u) != size_read(%u) for %s\n",
1940 : (unsigned int)size,
1941 : (unsigned int)size_read,
1942 : fname);
1943 : /* Use EOF to mean bad size. */
1944 0 : return NT_STATUS_END_OF_FILE;
1945 : }
1946 11 : return NT_STATUS_OK;
1947 : }
1948 :
1949 : /* Ensure cli_ftruncate() works for SMB2. */
1950 :
1951 1 : bool run_smb2_ftruncate(int dummy)
1952 : {
1953 1 : struct cli_state *cli = NULL;
1954 1 : const char *fname = "smb2_ftruncate.txt";
1955 1 : uint16_t fnum = (uint16_t)-1;
1956 1 : bool correct = false;
1957 1 : size_t buflen = 1024*1024;
1958 1 : uint8_t *buf = NULL;
1959 : unsigned int i;
1960 : NTSTATUS status;
1961 :
1962 1 : printf("Starting SMB2-FTRUNCATE\n");
1963 :
1964 1 : if (!torture_init_connection(&cli)) {
1965 0 : goto fail;
1966 : }
1967 :
1968 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
1969 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
1970 1 : if (!NT_STATUS_IS_OK(status)) {
1971 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1972 0 : goto fail;
1973 : }
1974 :
1975 1 : status = cli_session_setup_creds(cli, torture_creds);
1976 1 : if (!NT_STATUS_IS_OK(status)) {
1977 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
1978 0 : goto fail;
1979 : }
1980 :
1981 1 : status = cli_tree_connect(cli, share, "?????", NULL);
1982 1 : if (!NT_STATUS_IS_OK(status)) {
1983 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1984 0 : goto fail;
1985 : }
1986 :
1987 1 : cli_setatr(cli, fname, 0, 0);
1988 1 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1989 :
1990 1 : status = cli_ntcreate(cli,
1991 : fname,
1992 : 0,
1993 : GENERIC_ALL_ACCESS,
1994 : FILE_ATTRIBUTE_NORMAL,
1995 : FILE_SHARE_NONE,
1996 : FILE_CREATE,
1997 : 0,
1998 : 0,
1999 : &fnum,
2000 : NULL);
2001 :
2002 1 : if (!NT_STATUS_IS_OK(status)) {
2003 0 : printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2004 0 : goto fail;
2005 : }
2006 :
2007 1 : buf = talloc_zero_array(cli, uint8_t, buflen);
2008 1 : if (buf == NULL) {
2009 0 : goto fail;
2010 : }
2011 :
2012 : /* Write 1MB. */
2013 1 : status = cli_writeall(cli,
2014 : fnum,
2015 : 0,
2016 : buf,
2017 : 0,
2018 : buflen,
2019 : NULL);
2020 :
2021 1 : if (!NT_STATUS_IS_OK(status)) {
2022 0 : printf("write of %u to %s failed (%s)\n",
2023 : (unsigned int)buflen,
2024 : fname,
2025 : nt_errstr(status));
2026 0 : goto fail;
2027 : }
2028 :
2029 1 : status = check_size(cli, fnum, fname, buflen);
2030 1 : if (!NT_STATUS_IS_OK(status)) {
2031 0 : goto fail;
2032 : }
2033 :
2034 : /* Now ftruncate. */
2035 11 : for ( i = 0; i < 10; i++) {
2036 10 : status = cli_ftruncate(cli, fnum, i*1024);
2037 10 : if (!NT_STATUS_IS_OK(status)) {
2038 0 : printf("cli_ftruncate %u of %s failed (%s)\n",
2039 : (unsigned int)i*1024,
2040 : fname,
2041 : nt_errstr(status));
2042 0 : goto fail;
2043 : }
2044 10 : status = check_size(cli, fnum, fname, i*1024);
2045 10 : if (!NT_STATUS_IS_OK(status)) {
2046 0 : goto fail;
2047 : }
2048 : }
2049 :
2050 1 : correct = true;
2051 :
2052 1 : fail:
2053 :
2054 1 : if (cli == NULL) {
2055 0 : return false;
2056 : }
2057 :
2058 1 : if (fnum != (uint16_t)-1) {
2059 1 : cli_close(cli, fnum);
2060 : }
2061 1 : cli_setatr(cli, fname, 0, 0);
2062 1 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2063 :
2064 1 : if (!torture_close_connection(cli)) {
2065 0 : correct = false;
2066 : }
2067 1 : return correct;
2068 : }
2069 :
2070 : /* Ensure SMB2 flush on directories behaves correctly. */
2071 :
2072 1 : static bool test_dir_fsync(struct cli_state *cli, const char *path)
2073 : {
2074 : NTSTATUS status;
2075 : uint64_t fid_persistent, fid_volatile;
2076 1 : uint8_t *dir_data = NULL;
2077 1 : uint32_t dir_data_length = 0;
2078 :
2079 : /* Open directory - no write abilities. */
2080 1 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2081 : cli->smb2.tcon, path,
2082 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2083 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2084 : SEC_STD_SYNCHRONIZE|
2085 : SEC_DIR_LIST|
2086 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2087 : 0, /* file_attributes, */
2088 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2089 : FILE_OPEN, /* create_disposition, */
2090 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2091 : NULL, /* smb2_create_blobs *blobs */
2092 : &fid_persistent,
2093 : &fid_volatile,
2094 : NULL, NULL, NULL);
2095 1 : if (!NT_STATUS_IS_OK(status)) {
2096 0 : printf("smb2cli_create '%s' (readonly) returned %s\n",
2097 : path,
2098 : nt_errstr(status));
2099 0 : return false;
2100 : }
2101 :
2102 2 : status = smb2cli_query_directory(
2103 1 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2104 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2105 : talloc_tos(), &dir_data, &dir_data_length);
2106 :
2107 1 : if (!NT_STATUS_IS_OK(status)) {
2108 0 : printf("smb2cli_query_directory returned %s\n",
2109 : nt_errstr(status));
2110 0 : return false;
2111 : }
2112 :
2113 : /* Open directory no write access. Flush should fail. */
2114 :
2115 1 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2116 : cli->smb2.tcon, fid_persistent, fid_volatile);
2117 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2118 1 : printf("smb2cli_flush on a read-only directory returned %s\n",
2119 : nt_errstr(status));
2120 1 : return false;
2121 : }
2122 :
2123 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2124 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2125 0 : if (!NT_STATUS_IS_OK(status)) {
2126 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2127 0 : return false;
2128 : }
2129 :
2130 : /* Open directory write-attributes only. Flush should still fail. */
2131 :
2132 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2133 : cli->smb2.tcon, path,
2134 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2135 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2136 : SEC_STD_SYNCHRONIZE|
2137 : SEC_DIR_LIST|
2138 : SEC_DIR_WRITE_ATTRIBUTE|
2139 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2140 : 0, /* file_attributes, */
2141 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2142 : FILE_OPEN, /* create_disposition, */
2143 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2144 : NULL, /* smb2_create_blobs *blobs */
2145 : &fid_persistent,
2146 : &fid_volatile,
2147 : NULL, NULL, NULL);
2148 0 : if (!NT_STATUS_IS_OK(status)) {
2149 0 : printf("smb2cli_create '%s' (write attr) returned %s\n",
2150 : path,
2151 : nt_errstr(status));
2152 0 : return false;
2153 : }
2154 :
2155 0 : status = smb2cli_query_directory(
2156 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2157 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2158 : talloc_tos(), &dir_data, &dir_data_length);
2159 :
2160 0 : if (!NT_STATUS_IS_OK(status)) {
2161 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2162 0 : return false;
2163 : }
2164 :
2165 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2166 : cli->smb2.tcon, fid_persistent, fid_volatile);
2167 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2168 0 : printf("smb2cli_flush on a write-attributes directory "
2169 : "returned %s\n",
2170 : nt_errstr(status));
2171 0 : return false;
2172 : }
2173 :
2174 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2175 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2176 0 : if (!NT_STATUS_IS_OK(status)) {
2177 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2178 0 : return false;
2179 : }
2180 :
2181 : /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2182 :
2183 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2184 : cli->smb2.tcon, path,
2185 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2186 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2187 : SEC_STD_SYNCHRONIZE|
2188 : SEC_DIR_LIST|
2189 : SEC_DIR_ADD_FILE, /* desired_access, */
2190 : 0, /* file_attributes, */
2191 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2192 : FILE_OPEN, /* create_disposition, */
2193 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2194 : NULL, /* smb2_create_blobs *blobs */
2195 : &fid_persistent,
2196 : &fid_volatile,
2197 : NULL, NULL, NULL);
2198 0 : if (!NT_STATUS_IS_OK(status)) {
2199 0 : printf("smb2cli_create '%s' (write FILE access) returned %s\n",
2200 : path,
2201 : nt_errstr(status));
2202 0 : return false;
2203 : }
2204 :
2205 0 : status = smb2cli_query_directory(
2206 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2207 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2208 : talloc_tos(), &dir_data, &dir_data_length);
2209 :
2210 0 : if (!NT_STATUS_IS_OK(status)) {
2211 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2212 0 : return false;
2213 : }
2214 :
2215 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2216 : cli->smb2.tcon, fid_persistent, fid_volatile);
2217 0 : if (!NT_STATUS_IS_OK(status)) {
2218 0 : printf("smb2cli_flush on a directory returned %s\n",
2219 : nt_errstr(status));
2220 0 : return false;
2221 : }
2222 :
2223 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2224 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2225 0 : if (!NT_STATUS_IS_OK(status)) {
2226 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2227 0 : return false;
2228 : }
2229 :
2230 : /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2231 :
2232 0 : status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2233 : cli->smb2.tcon, path,
2234 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2235 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2236 : SEC_STD_SYNCHRONIZE|
2237 : SEC_DIR_LIST|
2238 : SEC_DIR_ADD_SUBDIR, /* desired_access, */
2239 : 0, /* file_attributes, */
2240 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2241 : FILE_OPEN, /* create_disposition, */
2242 : FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2243 : NULL, /* smb2_create_blobs *blobs */
2244 : &fid_persistent,
2245 : &fid_volatile,
2246 : NULL, NULL, NULL);
2247 0 : if (!NT_STATUS_IS_OK(status)) {
2248 0 : printf("smb2cli_create '%s' (write DIR access) returned %s\n",
2249 : path,
2250 : nt_errstr(status));
2251 0 : return false;
2252 : }
2253 :
2254 0 : status = smb2cli_query_directory(
2255 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2256 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2257 : talloc_tos(), &dir_data, &dir_data_length);
2258 :
2259 0 : if (!NT_STATUS_IS_OK(status)) {
2260 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2261 0 : return false;
2262 : }
2263 :
2264 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2265 : cli->smb2.tcon, fid_persistent, fid_volatile);
2266 0 : if (!NT_STATUS_IS_OK(status)) {
2267 0 : printf("smb2cli_flush on a directory returned %s\n",
2268 : nt_errstr(status));
2269 0 : return false;
2270 : }
2271 :
2272 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2273 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2274 0 : if (!NT_STATUS_IS_OK(status)) {
2275 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2276 0 : return false;
2277 : }
2278 :
2279 :
2280 0 : return true;
2281 : }
2282 :
2283 1 : bool run_smb2_dir_fsync(int dummy)
2284 : {
2285 1 : struct cli_state *cli = NULL;
2286 : NTSTATUS status;
2287 1 : bool bret = false;
2288 1 : const char *dname = "fsync_test_dir";
2289 :
2290 1 : printf("Starting SMB2-DIR-FSYNC\n");
2291 :
2292 1 : if (!torture_init_connection(&cli)) {
2293 0 : return false;
2294 : }
2295 :
2296 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
2297 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2298 1 : if (!NT_STATUS_IS_OK(status)) {
2299 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2300 0 : return false;
2301 : }
2302 :
2303 1 : status = cli_session_setup_creds(cli, torture_creds);
2304 1 : if (!NT_STATUS_IS_OK(status)) {
2305 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2306 0 : return false;
2307 : }
2308 :
2309 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2310 1 : if (!NT_STATUS_IS_OK(status)) {
2311 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2312 0 : return false;
2313 : }
2314 :
2315 1 : (void)cli_rmdir(cli, dname);
2316 1 : status = cli_mkdir(cli, dname);
2317 1 : if (!NT_STATUS_IS_OK(status)) {
2318 0 : printf("cli_mkdir(%s) returned %s\n",
2319 : dname,
2320 : nt_errstr(status));
2321 0 : return false;
2322 : }
2323 :
2324 : /* Test on a subdirectory. */
2325 1 : bret = test_dir_fsync(cli, dname);
2326 1 : if (bret == false) {
2327 1 : (void)cli_rmdir(cli, dname);
2328 1 : return false;
2329 : }
2330 0 : (void)cli_rmdir(cli, dname);
2331 :
2332 : /* Test on the root handle of a share. */
2333 0 : bret = test_dir_fsync(cli, "");
2334 0 : if (bret == false) {
2335 0 : return false;
2336 : }
2337 0 : return true;
2338 : }
2339 :
2340 1 : bool run_smb2_path_slash(int dummy)
2341 : {
2342 1 : struct cli_state *cli = NULL;
2343 : NTSTATUS status;
2344 : uint64_t fid_persistent;
2345 : uint64_t fid_volatile;
2346 1 : const char *dname_noslash = "smb2_dir_slash";
2347 1 : const char *dname_backslash = "smb2_dir_slash\\";
2348 1 : const char *dname_slash = "smb2_dir_slash/";
2349 1 : const char *fname_noslash = "smb2_file_slash";
2350 1 : const char *fname_backslash = "smb2_file_slash\\";
2351 1 : const char *fname_slash = "smb2_file_slash/";
2352 :
2353 1 : printf("Starting SMB2-PATH-SLASH\n");
2354 :
2355 1 : if (!torture_init_connection(&cli)) {
2356 0 : return false;
2357 : }
2358 :
2359 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
2360 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2361 1 : if (!NT_STATUS_IS_OK(status)) {
2362 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2363 0 : return false;
2364 : }
2365 :
2366 1 : status = cli_session_setup_creds(cli, torture_creds);
2367 1 : if (!NT_STATUS_IS_OK(status)) {
2368 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2369 0 : return false;
2370 : }
2371 :
2372 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2373 1 : if (!NT_STATUS_IS_OK(status)) {
2374 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2375 0 : return false;
2376 : }
2377 :
2378 1 : (void)cli_unlink(cli, dname_noslash, 0);
2379 1 : (void)cli_rmdir(cli, dname_noslash);
2380 1 : (void)cli_unlink(cli, fname_noslash, 0);
2381 1 : (void)cli_rmdir(cli, fname_noslash);
2382 :
2383 : /* Try to create a directory with the backslash name. */
2384 3 : status = smb2cli_create(cli->conn,
2385 1 : cli->timeout,
2386 1 : cli->smb2.session,
2387 1 : cli->smb2.tcon,
2388 : dname_backslash,
2389 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2390 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2391 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2392 : 0, /* file_attributes, */
2393 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2394 : FILE_CREATE, /* create_disposition, */
2395 : FILE_DIRECTORY_FILE, /* create_options, */
2396 : NULL, /* smb2_create_blobs *blobs */
2397 : &fid_persistent,
2398 : &fid_volatile,
2399 : NULL, NULL, NULL);
2400 :
2401 : /* directory ending in '\\' should be success. */
2402 :
2403 1 : if (!NT_STATUS_IS_OK(status)) {
2404 0 : printf("smb2cli_create '%s' returned %s - "
2405 : "should be NT_STATUS_OK\n",
2406 : dname_backslash,
2407 : nt_errstr(status));
2408 0 : return false;
2409 : }
2410 4 : status = smb2cli_close(cli->conn,
2411 1 : cli->timeout,
2412 1 : cli->smb2.session,
2413 1 : cli->smb2.tcon,
2414 : 0,
2415 : fid_persistent,
2416 : fid_volatile);
2417 1 : if (!NT_STATUS_IS_OK(status)) {
2418 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2419 0 : return false;
2420 : }
2421 :
2422 1 : (void)cli_rmdir(cli, dname_noslash);
2423 :
2424 : /* Try to create a directory with the slash name. */
2425 3 : status = smb2cli_create(cli->conn,
2426 1 : cli->timeout,
2427 1 : cli->smb2.session,
2428 1 : cli->smb2.tcon,
2429 : dname_slash,
2430 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2431 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2432 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2433 : 0, /* file_attributes, */
2434 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2435 : FILE_CREATE, /* create_disposition, */
2436 : FILE_DIRECTORY_FILE, /* create_options, */
2437 : NULL, /* smb2_create_blobs *blobs */
2438 : &fid_persistent,
2439 : &fid_volatile,
2440 : NULL, NULL, NULL);
2441 :
2442 : /* directory ending in '/' is an error. */
2443 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2444 0 : printf("smb2cli_create '%s' returned %s - "
2445 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2446 : dname_slash,
2447 : nt_errstr(status));
2448 0 : if (NT_STATUS_IS_OK(status)) {
2449 0 : (void)smb2cli_close(cli->conn,
2450 0 : cli->timeout,
2451 0 : cli->smb2.session,
2452 0 : cli->smb2.tcon,
2453 : 0,
2454 : fid_persistent,
2455 : fid_volatile);
2456 : }
2457 0 : (void)cli_rmdir(cli, dname_noslash);
2458 0 : return false;
2459 : }
2460 :
2461 1 : (void)cli_rmdir(cli, dname_noslash);
2462 :
2463 : /* Try to create a file with the backslash name. */
2464 3 : status = smb2cli_create(cli->conn,
2465 1 : cli->timeout,
2466 1 : cli->smb2.session,
2467 1 : cli->smb2.tcon,
2468 : fname_backslash,
2469 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2470 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2471 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2472 : 0, /* file_attributes, */
2473 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2474 : FILE_CREATE, /* create_disposition, */
2475 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2476 : NULL, /* smb2_create_blobs *blobs */
2477 : &fid_persistent,
2478 : &fid_volatile,
2479 : NULL, NULL, NULL);
2480 :
2481 : /* file ending in '\\' should be error. */
2482 :
2483 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2484 1 : printf("smb2cli_create '%s' returned %s - "
2485 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2486 : fname_backslash,
2487 : nt_errstr(status));
2488 1 : if (NT_STATUS_IS_OK(status)) {
2489 4 : (void)smb2cli_close(cli->conn,
2490 1 : cli->timeout,
2491 1 : cli->smb2.session,
2492 1 : cli->smb2.tcon,
2493 : 0,
2494 : fid_persistent,
2495 : fid_volatile);
2496 : }
2497 1 : (void)cli_unlink(cli, fname_noslash, 0);
2498 1 : return false;
2499 : }
2500 :
2501 0 : (void)cli_unlink(cli, fname_noslash, 0);
2502 :
2503 : /* Try to create a file with the slash name. */
2504 0 : status = smb2cli_create(cli->conn,
2505 0 : cli->timeout,
2506 0 : cli->smb2.session,
2507 0 : cli->smb2.tcon,
2508 : fname_slash,
2509 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2510 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2511 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2512 : 0, /* file_attributes, */
2513 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2514 : FILE_CREATE, /* create_disposition, */
2515 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2516 : NULL, /* smb2_create_blobs *blobs */
2517 : &fid_persistent,
2518 : &fid_volatile,
2519 : NULL, NULL, NULL);
2520 :
2521 : /* file ending in '/' should be error. */
2522 :
2523 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2524 0 : printf("smb2cli_create '%s' returned %s - "
2525 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2526 : fname_slash,
2527 : nt_errstr(status));
2528 0 : if (NT_STATUS_IS_OK(status)) {
2529 0 : (void)smb2cli_close(cli->conn,
2530 0 : cli->timeout,
2531 0 : cli->smb2.session,
2532 0 : cli->smb2.tcon,
2533 : 0,
2534 : fid_persistent,
2535 : fid_volatile);
2536 : }
2537 0 : (void)cli_unlink(cli, fname_noslash, 0);
2538 0 : return false;
2539 : }
2540 :
2541 0 : (void)cli_unlink(cli, fname_noslash, 0);
2542 0 : return true;
2543 : }
2544 :
2545 : /*
2546 : * NB. This can only work against a server where
2547 : * the connecting user has been granted SeSecurityPrivilege.
2548 : *
2549 : * 1). Create a test file.
2550 : * 2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
2551 : * NB. SMB2-only behavior.
2552 : * 3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2553 : * 4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
2554 : * 5). Close (3).
2555 : * 6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2556 : * 7). Write SACL. Success.
2557 : * 8). Close (4).
2558 : * 9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2559 : * 10). Read SACL. Success.
2560 : * 11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
2561 : * 12). Close (9).
2562 : */
2563 :
2564 0 : bool run_smb2_sacl(int dummy)
2565 : {
2566 0 : struct cli_state *cli = NULL;
2567 : NTSTATUS status;
2568 0 : struct security_descriptor *sd_dacl = NULL;
2569 0 : struct security_descriptor *sd_sacl = NULL;
2570 0 : const char *fname = "sacl_test_file";
2571 0 : uint16_t fnum = (uint16_t)-1;
2572 :
2573 0 : printf("Starting SMB2-SACL\n");
2574 :
2575 0 : if (!torture_init_connection(&cli)) {
2576 0 : return false;
2577 : }
2578 :
2579 0 : status = smbXcli_negprot(cli->conn,
2580 0 : cli->timeout,
2581 : PROTOCOL_SMB2_02,
2582 : PROTOCOL_SMB3_11);
2583 0 : if (!NT_STATUS_IS_OK(status)) {
2584 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2585 0 : return false;
2586 : }
2587 :
2588 0 : status = cli_session_setup_creds(cli, torture_creds);
2589 0 : if (!NT_STATUS_IS_OK(status)) {
2590 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2591 0 : return false;
2592 : }
2593 :
2594 0 : status = cli_tree_connect(cli, share, "?????", NULL);
2595 0 : if (!NT_STATUS_IS_OK(status)) {
2596 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2597 0 : return false;
2598 : }
2599 :
2600 0 : (void)cli_unlink(cli, fname, 0);
2601 :
2602 : /* First create a file. */
2603 0 : status = cli_ntcreate(cli,
2604 : fname,
2605 : 0,
2606 : GENERIC_ALL_ACCESS,
2607 : FILE_ATTRIBUTE_NORMAL,
2608 : FILE_SHARE_NONE,
2609 : FILE_CREATE,
2610 : 0,
2611 : 0,
2612 : &fnum,
2613 : NULL);
2614 :
2615 0 : if (!NT_STATUS_IS_OK(status)) {
2616 0 : printf("Create of %s failed (%s)\n",
2617 : fname,
2618 : nt_errstr(status));
2619 0 : goto fail;
2620 : }
2621 :
2622 0 : cli_close(cli, fnum);
2623 0 : fnum = (uint16_t)-1;
2624 :
2625 : /*
2626 : * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
2627 : * This should fail with NT_STATUS_ACCESS_DENIED - but
2628 : * only against an SMB2 server. SMB1 allows this as tested
2629 : * in SMB1-SYSTEM-SECURITY.
2630 : */
2631 :
2632 0 : status = cli_smb2_create_fnum(cli,
2633 : fname,
2634 : SMB2_OPLOCK_LEVEL_NONE,
2635 : SMB2_IMPERSONATION_IMPERSONATION,
2636 : SEC_FLAG_SYSTEM_SECURITY, /* desired access */
2637 : 0, /* file_attributes, */
2638 : FILE_SHARE_READ|
2639 : FILE_SHARE_WRITE|
2640 : FILE_SHARE_DELETE, /* share_access, */
2641 : FILE_OPEN, /* create_disposition, */
2642 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2643 : NULL, /* in_cblobs. */
2644 : &fnum, /* fnum */
2645 : NULL, /* smb_create_returns */
2646 : talloc_tos(), /* mem_ctx */
2647 : NULL); /* out_cblobs */
2648 :
2649 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
2650 0 : printf("SMB2-SACL-TEST can only work with a user "
2651 : "who has been granted SeSecurityPrivilege.\n"
2652 : "This is the "
2653 : "\"Manage auditing and security log\""
2654 : "privilege setting on Windows\n");
2655 0 : goto fail;
2656 : }
2657 :
2658 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2659 0 : printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
2660 : "got %s - should fail with ACCESS_DENIED\n",
2661 : fname,
2662 : nt_errstr(status));
2663 0 : goto fail;
2664 : }
2665 :
2666 : /*
2667 : * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2668 : */
2669 :
2670 0 : status = cli_smb2_create_fnum(cli,
2671 : fname,
2672 : SMB2_OPLOCK_LEVEL_NONE,
2673 : SMB2_IMPERSONATION_IMPERSONATION,
2674 : SEC_FLAG_SYSTEM_SECURITY|
2675 : FILE_WRITE_ATTRIBUTES, /* desired access */
2676 : 0, /* file_attributes, */
2677 : FILE_SHARE_READ|
2678 : FILE_SHARE_WRITE|
2679 : FILE_SHARE_DELETE, /* share_access, */
2680 : FILE_OPEN, /* create_disposition, */
2681 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2682 : NULL, /* in_cblobs. */
2683 : &fnum, /* fnum */
2684 : NULL, /* smb_create_returns */
2685 : talloc_tos(), /* mem_ctx */
2686 : NULL); /* out_cblobs */
2687 :
2688 0 : if (!NT_STATUS_IS_OK(status)) {
2689 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2690 : "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2691 : fname,
2692 : nt_errstr(status));
2693 0 : goto fail;
2694 : }
2695 :
2696 : /* Create an SD with a SACL. */
2697 0 : sd_sacl = security_descriptor_sacl_create(talloc_tos(),
2698 : 0,
2699 : NULL, /* owner. */
2700 : NULL, /* group. */
2701 : /* first ACE. */
2702 : SID_WORLD,
2703 : SEC_ACE_TYPE_SYSTEM_AUDIT,
2704 : SEC_GENERIC_ALL,
2705 : SEC_ACE_FLAG_FAILED_ACCESS,
2706 : NULL);
2707 :
2708 0 : if (sd_sacl == NULL) {
2709 0 : printf("Out of memory creating SACL\n");
2710 0 : goto fail;
2711 : }
2712 :
2713 : /*
2714 : * Write the SACL SD. This should fail
2715 : * even though we have SEC_FLAG_SYSTEM_SECURITY,
2716 : * as it seems to also need WRITE_DAC access.
2717 : */
2718 0 : status = cli_set_security_descriptor(cli,
2719 : fnum,
2720 : SECINFO_DACL|SECINFO_SACL,
2721 : sd_sacl);
2722 :
2723 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2724 0 : printf("Writing SACL on file %s got (%s) "
2725 : "should have failed with ACCESS_DENIED.\n",
2726 : fname,
2727 : nt_errstr(status));
2728 0 : goto fail;
2729 : }
2730 :
2731 : /* And close. */
2732 0 : cli_smb2_close_fnum(cli, fnum);
2733 0 : fnum = (uint16_t)-1;
2734 :
2735 : /*
2736 : * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2737 : */
2738 :
2739 0 : status = cli_smb2_create_fnum(cli,
2740 : fname,
2741 : SMB2_OPLOCK_LEVEL_NONE,
2742 : SMB2_IMPERSONATION_IMPERSONATION,
2743 : SEC_FLAG_SYSTEM_SECURITY|
2744 : SEC_STD_WRITE_DAC, /* desired access */
2745 : 0, /* file_attributes, */
2746 : FILE_SHARE_READ|
2747 : FILE_SHARE_WRITE|
2748 : FILE_SHARE_DELETE, /* share_access, */
2749 : FILE_OPEN, /* create_disposition, */
2750 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2751 : NULL, /* in_cblobs. */
2752 : &fnum, /* fnum */
2753 : NULL, /* smb_create_returns */
2754 : talloc_tos(), /* mem_ctx */
2755 : NULL); /* out_cblobs */
2756 :
2757 0 : if (!NT_STATUS_IS_OK(status)) {
2758 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2759 : "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2760 : fname,
2761 : nt_errstr(status));
2762 0 : goto fail;
2763 : }
2764 :
2765 : /*
2766 : * Write the SACL SD. This should now succeed
2767 : * as we have both SEC_FLAG_SYSTEM_SECURITY
2768 : * and WRITE_DAC access.
2769 : */
2770 0 : status = cli_set_security_descriptor(cli,
2771 : fnum,
2772 : SECINFO_DACL|SECINFO_SACL,
2773 : sd_sacl);
2774 :
2775 0 : if (!NT_STATUS_IS_OK(status)) {
2776 0 : printf("cli_set_security_descriptor SACL "
2777 : "on file %s failed (%s)\n",
2778 : fname,
2779 : nt_errstr(status));
2780 0 : goto fail;
2781 : }
2782 :
2783 : /* And close. */
2784 0 : cli_smb2_close_fnum(cli, fnum);
2785 0 : fnum = (uint16_t)-1;
2786 :
2787 : /* We're done with the sacl we made. */
2788 0 : TALLOC_FREE(sd_sacl);
2789 :
2790 : /*
2791 : * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2792 : * This gives us access to the SACL.
2793 : */
2794 :
2795 0 : status = cli_smb2_create_fnum(cli,
2796 : fname,
2797 : SMB2_OPLOCK_LEVEL_NONE,
2798 : SMB2_IMPERSONATION_IMPERSONATION,
2799 : SEC_FLAG_SYSTEM_SECURITY|
2800 : FILE_READ_ATTRIBUTES, /* desired access */
2801 : 0, /* file_attributes, */
2802 : FILE_SHARE_READ|
2803 : FILE_SHARE_WRITE|
2804 : FILE_SHARE_DELETE, /* share_access, */
2805 : FILE_OPEN, /* create_disposition, */
2806 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2807 : NULL, /* in_cblobs. */
2808 : &fnum, /* fnum */
2809 : NULL, /* smb_create_returns */
2810 : talloc_tos(), /* mem_ctx */
2811 : NULL); /* out_cblobs */
2812 :
2813 0 : if (!NT_STATUS_IS_OK(status)) {
2814 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2815 : "FILE_READ_ATTRIBUTES) failed (%s)\n",
2816 : fname,
2817 : nt_errstr(status));
2818 0 : goto fail;
2819 : }
2820 :
2821 : /* Try and read the SACL - should succeed. */
2822 0 : status = cli_query_security_descriptor(
2823 : cli, fnum, SECINFO_SACL, talloc_tos(), &sd_sacl);
2824 :
2825 0 : if (!NT_STATUS_IS_OK(status)) {
2826 0 : printf("Read SACL from file %s failed (%s)\n",
2827 : fname,
2828 : nt_errstr(status));
2829 0 : goto fail;
2830 : }
2831 :
2832 0 : TALLOC_FREE(sd_sacl);
2833 :
2834 : /*
2835 : * Try and read the DACL - should fail as we have
2836 : * no READ_DAC access.
2837 : */
2838 0 : status = cli_query_security_descriptor(
2839 : cli, fnum, SECINFO_DACL, talloc_tos(), &sd_sacl);
2840 :
2841 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2842 0 : printf("Reading DACL on file %s got (%s) "
2843 : "should have failed with ACCESS_DENIED.\n",
2844 : fname,
2845 : nt_errstr(status));
2846 0 : goto fail;
2847 : }
2848 :
2849 0 : if (fnum != (uint16_t)-1) {
2850 0 : cli_smb2_close_fnum(cli, fnum);
2851 0 : fnum = (uint16_t)-1;
2852 : }
2853 :
2854 0 : TALLOC_FREE(sd_dacl);
2855 0 : TALLOC_FREE(sd_sacl);
2856 :
2857 0 : (void)cli_unlink(cli, fname, 0);
2858 0 : return true;
2859 :
2860 0 : fail:
2861 :
2862 0 : TALLOC_FREE(sd_dacl);
2863 0 : TALLOC_FREE(sd_sacl);
2864 :
2865 0 : if (fnum != (uint16_t)-1) {
2866 0 : cli_smb2_close_fnum(cli, fnum);
2867 0 : fnum = (uint16_t)-1;
2868 : }
2869 :
2870 0 : (void)cli_unlink(cli, fname, 0);
2871 0 : return false;
2872 : }
2873 :
2874 1 : bool run_smb2_quota1(int dummy)
2875 : {
2876 1 : struct cli_state *cli = NULL;
2877 : NTSTATUS status;
2878 1 : uint16_t fnum = (uint16_t)-1;
2879 1 : SMB_NTQUOTA_STRUCT qt = {0};
2880 :
2881 1 : printf("Starting SMB2-QUOTA1\n");
2882 :
2883 1 : if (!torture_init_connection(&cli)) {
2884 0 : return false;
2885 : }
2886 :
2887 1 : status = smbXcli_negprot(cli->conn,
2888 1 : cli->timeout,
2889 : PROTOCOL_SMB2_02,
2890 : PROTOCOL_SMB3_11);
2891 1 : if (!NT_STATUS_IS_OK(status)) {
2892 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2893 0 : return false;
2894 : }
2895 :
2896 1 : status = cli_session_setup_creds(cli, torture_creds);
2897 1 : if (!NT_STATUS_IS_OK(status)) {
2898 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2899 0 : return false;
2900 : }
2901 :
2902 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2903 1 : if (!NT_STATUS_IS_OK(status)) {
2904 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2905 0 : return false;
2906 : }
2907 :
2908 1 : status = cli_smb2_create_fnum(
2909 : cli,
2910 : "\\",
2911 : SMB2_OPLOCK_LEVEL_NONE,
2912 : SMB2_IMPERSONATION_IMPERSONATION,
2913 : SEC_GENERIC_READ, /* desired access */
2914 : 0, /* file_attributes, */
2915 : FILE_SHARE_READ|
2916 : FILE_SHARE_WRITE|
2917 : FILE_SHARE_DELETE, /* share_access, */
2918 : FILE_OPEN, /* create_disposition, */
2919 : FILE_DIRECTORY_FILE, /* create_options, */
2920 : NULL, /* in_cblobs. */
2921 : &fnum, /* fnum */
2922 : NULL, /* smb_create_returns */
2923 : NULL, /* mem_ctx */
2924 : NULL); /* out_cblobs */
2925 1 : if (!NT_STATUS_IS_OK(status)) {
2926 0 : printf("cli_smb2_create_fnum failed: %s\n", nt_errstr(status));
2927 0 : return false;
2928 : }
2929 :
2930 1 : status = cli_smb2_get_user_quota(cli, fnum, &qt);
2931 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
2932 1 : printf("cli_smb2_get_user_quota returned %s, expected "
2933 : "NT_STATUS_INVALID_HANDLE\n",
2934 : nt_errstr(status));
2935 1 : return false;
2936 : }
2937 :
2938 0 : return true;
2939 : }
2940 :
2941 0 : bool run_smb2_stream_acl(int dummy)
2942 : {
2943 0 : struct cli_state *cli = NULL;
2944 : NTSTATUS status;
2945 0 : uint16_t fnum = (uint16_t)-1;
2946 0 : const char *fname = "stream_acl_test_file";
2947 0 : const char *sname = "stream_acl_test_file:streamname";
2948 0 : struct security_descriptor *sd_dacl = NULL;
2949 0 : bool ret = false;
2950 :
2951 0 : printf("SMB2 stream acl\n");
2952 :
2953 0 : if (!torture_init_connection(&cli)) {
2954 0 : return false;
2955 : }
2956 :
2957 0 : status = smbXcli_negprot(cli->conn,
2958 0 : cli->timeout,
2959 : PROTOCOL_SMB2_02,
2960 : PROTOCOL_SMB3_11);
2961 0 : if (!NT_STATUS_IS_OK(status)) {
2962 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2963 0 : return false;
2964 : }
2965 :
2966 0 : status = cli_session_setup_creds(cli, torture_creds);
2967 0 : if (!NT_STATUS_IS_OK(status)) {
2968 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2969 0 : return false;
2970 : }
2971 :
2972 0 : status = cli_tree_connect(cli, share, "?????", NULL);
2973 0 : if (!NT_STATUS_IS_OK(status)) {
2974 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2975 0 : return false;
2976 : }
2977 :
2978 : /* Ensure file doesn't exist. */
2979 0 : (void)cli_unlink(cli, fname, 0);
2980 :
2981 : /* Create the file. */
2982 0 : status = cli_ntcreate(cli,
2983 : fname,
2984 : 0,
2985 : GENERIC_ALL_ACCESS,
2986 : FILE_ATTRIBUTE_NORMAL,
2987 : FILE_SHARE_NONE,
2988 : FILE_CREATE,
2989 : 0,
2990 : 0,
2991 : &fnum,
2992 : NULL);
2993 :
2994 0 : if (!NT_STATUS_IS_OK(status)) {
2995 0 : printf("Create of %s failed (%s)\n",
2996 : fname,
2997 : nt_errstr(status));
2998 0 : goto fail;
2999 : }
3000 :
3001 : /* Close the handle. */
3002 0 : cli_smb2_close_fnum(cli, fnum);
3003 0 : fnum = (uint16_t)-1;
3004 :
3005 : /* Create the stream. */
3006 0 : status = cli_ntcreate(cli,
3007 : sname,
3008 : 0,
3009 : FILE_READ_DATA|
3010 : SEC_STD_READ_CONTROL|
3011 : SEC_STD_WRITE_DAC,
3012 : FILE_ATTRIBUTE_NORMAL,
3013 : FILE_SHARE_NONE,
3014 : FILE_CREATE,
3015 : 0,
3016 : 0,
3017 : &fnum,
3018 : NULL);
3019 :
3020 0 : if (!NT_STATUS_IS_OK(status)) {
3021 0 : printf("Create of %s failed (%s)\n",
3022 : sname,
3023 : nt_errstr(status));
3024 0 : goto fail;
3025 : }
3026 :
3027 : /* Close the handle. */
3028 0 : cli_smb2_close_fnum(cli, fnum);
3029 0 : fnum = (uint16_t)-1;
3030 :
3031 : /*
3032 : * Open the stream - for Samba this ensures
3033 : * we prove we have a pathref fsp.
3034 : */
3035 0 : status = cli_ntcreate(cli,
3036 : sname,
3037 : 0,
3038 : FILE_READ_DATA|
3039 : SEC_STD_READ_CONTROL|
3040 : SEC_STD_WRITE_DAC,
3041 : FILE_ATTRIBUTE_NORMAL,
3042 : FILE_SHARE_NONE,
3043 : FILE_OPEN,
3044 : 0,
3045 : 0,
3046 : &fnum,
3047 : NULL);
3048 :
3049 0 : if (!NT_STATUS_IS_OK(status)) {
3050 0 : printf("Open of %s failed (%s)\n",
3051 : sname,
3052 : nt_errstr(status));
3053 0 : goto fail;
3054 : }
3055 :
3056 : /* Read the security descriptor off the stream handle. */
3057 0 : status = cli_query_security_descriptor(cli,
3058 : fnum,
3059 : SECINFO_DACL,
3060 : talloc_tos(),
3061 : &sd_dacl);
3062 :
3063 0 : if (!NT_STATUS_IS_OK(status)) {
3064 0 : printf("Reading DACL on stream %s got (%s)\n",
3065 : sname,
3066 : nt_errstr(status));
3067 0 : goto fail;
3068 : }
3069 :
3070 0 : if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3071 0 : sd_dacl->dacl->num_aces < 1) {
3072 0 : printf("Invalid DACL returned on stream %s "
3073 : "(this should not happen)\n",
3074 : sname);
3075 0 : goto fail;
3076 : }
3077 :
3078 : /*
3079 : * Ensure it allows FILE_READ_DATA in the first ace.
3080 : * It always should.
3081 : */
3082 0 : if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
3083 0 : printf("DACL->ace[0] returned on stream %s "
3084 : "doesn't have read access (should not happen)\n",
3085 : sname);
3086 0 : goto fail;
3087 : }
3088 :
3089 : /* Remove FILE_READ_DATA from the first ace and set. */
3090 0 : sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
3091 :
3092 0 : status = cli_set_security_descriptor(cli,
3093 : fnum,
3094 : SECINFO_DACL,
3095 : sd_dacl);
3096 :
3097 0 : if (!NT_STATUS_IS_OK(status)) {
3098 0 : printf("Setting DACL on stream %s got (%s)\n",
3099 : sname,
3100 : nt_errstr(status));
3101 0 : goto fail;
3102 : }
3103 :
3104 0 : TALLOC_FREE(sd_dacl);
3105 :
3106 : /* Read again and check it changed. */
3107 0 : status = cli_query_security_descriptor(cli,
3108 : fnum,
3109 : SECINFO_DACL,
3110 : talloc_tos(),
3111 : &sd_dacl);
3112 :
3113 0 : if (!NT_STATUS_IS_OK(status)) {
3114 0 : printf("Reading DACL on stream %s got (%s)\n",
3115 : sname,
3116 : nt_errstr(status));
3117 0 : goto fail;
3118 : }
3119 :
3120 0 : if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3121 0 : sd_dacl->dacl->num_aces < 1) {
3122 0 : printf("Invalid DACL (1) returned on stream %s "
3123 : "(this should not happen)\n",
3124 : sname);
3125 0 : goto fail;
3126 : }
3127 :
3128 : /* FILE_READ_DATA should be gone from the first ace. */
3129 0 : if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
3130 0 : printf("DACL on stream %s did not change\n",
3131 : sname);
3132 0 : goto fail;
3133 : }
3134 :
3135 0 : ret = true;
3136 :
3137 0 : fail:
3138 :
3139 0 : if (fnum != (uint16_t)-1) {
3140 0 : cli_smb2_close_fnum(cli, fnum);
3141 0 : fnum = (uint16_t)-1;
3142 : }
3143 :
3144 0 : (void)cli_unlink(cli, fname, 0);
3145 0 : return ret;
3146 : }
3147 :
3148 0 : static NTSTATUS list_fn(struct file_info *finfo,
3149 : const char *name,
3150 : void *state)
3151 : {
3152 0 : bool *matched = (bool *)state;
3153 0 : if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
3154 0 : *matched = true;
3155 : }
3156 0 : return NT_STATUS_OK;
3157 : }
3158 :
3159 : /*
3160 : * Must be run against a share with "smbd async dosmode = yes".
3161 : * Checks we can return DOS attriutes other than "N".
3162 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14758
3163 : */
3164 :
3165 0 : bool run_list_dir_async_test(int dummy)
3166 : {
3167 0 : struct cli_state *cli = NULL;
3168 : NTSTATUS status;
3169 0 : const char *dname = "ASYNC_DIR";
3170 0 : bool ret = false;
3171 0 : bool matched = false;
3172 :
3173 0 : printf("SMB2 list dir async\n");
3174 :
3175 0 : if (!torture_init_connection(&cli)) {
3176 0 : return false;
3177 : }
3178 :
3179 0 : status = smbXcli_negprot(cli->conn,
3180 0 : cli->timeout,
3181 : PROTOCOL_SMB2_02,
3182 : PROTOCOL_SMB3_11);
3183 0 : if (!NT_STATUS_IS_OK(status)) {
3184 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3185 0 : return false;
3186 : }
3187 :
3188 0 : status = cli_session_setup_creds(cli, torture_creds);
3189 0 : if (!NT_STATUS_IS_OK(status)) {
3190 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3191 0 : return false;
3192 : }
3193 :
3194 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3195 0 : if (!NT_STATUS_IS_OK(status)) {
3196 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3197 0 : return false;
3198 : }
3199 :
3200 : /* Ensure directory doesn't exist. */
3201 0 : (void)cli_rmdir(cli, dname);
3202 :
3203 0 : status = cli_mkdir(cli, dname);
3204 0 : if (!NT_STATUS_IS_OK(status)) {
3205 0 : printf("cli_mkdir %s returned %s\n", dname, nt_errstr(status));
3206 0 : return false;
3207 : }
3208 :
3209 0 : status = cli_list(cli,
3210 : dname,
3211 : FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_DIRECTORY,
3212 : list_fn,
3213 : &matched);
3214 0 : if (!NT_STATUS_IS_OK(status)) {
3215 0 : printf("cli_list %s returned %s\n", dname, nt_errstr(status));
3216 0 : goto fail;
3217 : }
3218 :
3219 0 : if (!matched) {
3220 0 : printf("Failed to find %s\n", dname);
3221 0 : goto fail;
3222 : }
3223 :
3224 0 : ret = true;
3225 :
3226 0 : fail:
3227 :
3228 0 : (void)cli_rmdir(cli, dname);
3229 0 : return ret;
3230 : }
3231 :
3232 : /*
3233 : * Test delete a directory fails if a file is created
3234 : * in a directory after the delete on close is set.
3235 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
3236 : */
3237 :
3238 0 : bool run_delete_on_close_non_empty(int dummy)
3239 : {
3240 0 : struct cli_state *cli = NULL;
3241 : NTSTATUS status;
3242 0 : const char *dname = "DEL_ON_CLOSE_DIR";
3243 0 : const char *fname = "DEL_ON_CLOSE_DIR\\testfile";
3244 0 : uint16_t fnum = (uint16_t)-1;
3245 0 : uint16_t fnum1 = (uint16_t)-1;
3246 0 : bool ret = false;
3247 :
3248 0 : printf("SMB2 delete on close nonempty\n");
3249 :
3250 0 : if (!torture_init_connection(&cli)) {
3251 0 : return false;
3252 : }
3253 :
3254 0 : status = smbXcli_negprot(cli->conn,
3255 0 : cli->timeout,
3256 : PROTOCOL_SMB2_02,
3257 : PROTOCOL_SMB3_11);
3258 0 : if (!NT_STATUS_IS_OK(status)) {
3259 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3260 0 : return false;
3261 : }
3262 :
3263 0 : status = cli_session_setup_creds(cli, torture_creds);
3264 0 : if (!NT_STATUS_IS_OK(status)) {
3265 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3266 0 : return false;
3267 : }
3268 :
3269 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3270 0 : if (!NT_STATUS_IS_OK(status)) {
3271 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3272 0 : return false;
3273 : }
3274 :
3275 : /* Ensure directory doesn't exist. */
3276 0 : (void)cli_unlink(cli,
3277 : fname,
3278 : FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3279 0 : (void)cli_rmdir(cli, dname);
3280 :
3281 : /* Create target directory. */
3282 0 : status = cli_ntcreate(cli,
3283 : dname,
3284 : 0,
3285 : DELETE_ACCESS|FILE_READ_DATA,
3286 : FILE_ATTRIBUTE_DIRECTORY,
3287 : FILE_SHARE_READ|
3288 : FILE_SHARE_WRITE|
3289 : FILE_SHARE_DELETE,
3290 : FILE_CREATE,
3291 : FILE_DIRECTORY_FILE,
3292 : 0,
3293 : &fnum,
3294 : NULL);
3295 0 : if (!NT_STATUS_IS_OK(status)) {
3296 0 : printf("cli_ntcreate for directory %s returned %s\n",
3297 : dname,
3298 : nt_errstr(status));
3299 0 : goto out;
3300 : }
3301 :
3302 : /* Now set the delete on close bit. */
3303 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3304 0 : if (!NT_STATUS_IS_OK(status)) {
3305 0 : printf("cli_cli_nt_delete_on_close set for directory "
3306 : "%s returned %s\n",
3307 : dname,
3308 : nt_errstr(status));
3309 0 : goto out;
3310 : }
3311 :
3312 : /* Create file inside target directory. */
3313 : /*
3314 : * NB. On Windows this will return NT_STATUS_DELETE_PENDING. Only on
3315 : * Samba will this succeed by default (the option "check parent
3316 : * directory delete on close" configures behaviour), but we're using
3317 : * this to test a race condition.
3318 : */
3319 0 : status = cli_ntcreate(cli,
3320 : fname,
3321 : 0,
3322 : FILE_READ_DATA,
3323 : FILE_ATTRIBUTE_NORMAL,
3324 : FILE_SHARE_READ|
3325 : FILE_SHARE_WRITE|
3326 : FILE_SHARE_DELETE,
3327 : FILE_CREATE,
3328 : 0,
3329 : 0,
3330 : &fnum1,
3331 : NULL);
3332 0 : if (!NT_STATUS_IS_OK(status)) {
3333 0 : printf("cli_ntcreate for file %s returned %s\n",
3334 : fname,
3335 : nt_errstr(status));
3336 0 : goto out;
3337 : }
3338 0 : cli_close(cli, fnum1);
3339 0 : fnum1 = (uint16_t)-1;
3340 :
3341 : /* Now the close should fail. */
3342 0 : status = cli_close(cli, fnum);
3343 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3344 0 : printf("cli_close for directory %s returned %s\n",
3345 : dname,
3346 : nt_errstr(status));
3347 0 : goto out;
3348 : }
3349 :
3350 0 : ret = true;
3351 :
3352 0 : out:
3353 :
3354 0 : if (fnum1 != (uint16_t)-1) {
3355 0 : cli_close(cli, fnum1);
3356 : }
3357 0 : if (fnum != (uint16_t)-1) {
3358 0 : cli_nt_delete_on_close(cli, fnum, 0);
3359 0 : cli_close(cli, fnum);
3360 : }
3361 0 : (void)cli_unlink(cli,
3362 : fname,
3363 : FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3364 0 : (void)cli_rmdir(cli, dname);
3365 0 : return ret;
3366 : }
3367 :
3368 0 : static NTSTATUS check_empty_fn(struct file_info *finfo,
3369 : const char *mask,
3370 : void *private_data)
3371 : {
3372 0 : unsigned int *pcount = (unsigned int *)private_data;
3373 :
3374 0 : if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
3375 0 : (*pcount)++;
3376 0 : return NT_STATUS_OK;
3377 : }
3378 0 : return NT_STATUS_DIRECTORY_NOT_EMPTY;
3379 : }
3380 :
3381 : /*
3382 : * Test setting the delete on close bit on a directory
3383 : * containing an unwritable file fails or succeeds
3384 : * an a share set with "hide unwritable = yes"
3385 : * depending on the setting of "delete veto files".
3386 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3387 : *
3388 : * First version. With "delete veto files = yes"
3389 : * setting the delete on close should succeed.
3390 : */
3391 :
3392 0 : bool run_delete_on_close_nonwrite_delete_yes_test(int dummy)
3393 : {
3394 0 : struct cli_state *cli = NULL;
3395 : NTSTATUS status;
3396 0 : const char *dname = "delete_veto_yes";
3397 0 : const char *list_dname = "delete_veto_yes\\*";
3398 0 : uint16_t fnum = (uint16_t)-1;
3399 0 : bool ret = false;
3400 0 : unsigned int list_count = 0;
3401 :
3402 0 : printf("SMB2 delete on close nonwrite - delete veto yes\n");
3403 :
3404 0 : if (!torture_init_connection(&cli)) {
3405 0 : return false;
3406 : }
3407 :
3408 0 : status = smbXcli_negprot(cli->conn,
3409 0 : cli->timeout,
3410 : PROTOCOL_SMB2_02,
3411 : PROTOCOL_SMB3_11);
3412 0 : if (!NT_STATUS_IS_OK(status)) {
3413 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3414 0 : return false;
3415 : }
3416 :
3417 0 : status = cli_session_setup_creds(cli, torture_creds);
3418 0 : if (!NT_STATUS_IS_OK(status)) {
3419 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3420 0 : return false;
3421 : }
3422 :
3423 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3424 0 : if (!NT_STATUS_IS_OK(status)) {
3425 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3426 0 : return false;
3427 : }
3428 :
3429 : /* Ensure target directory is seen as empty. */
3430 0 : status = cli_list(cli,
3431 : list_dname,
3432 : FILE_ATTRIBUTE_DIRECTORY |
3433 : FILE_ATTRIBUTE_HIDDEN |
3434 : FILE_ATTRIBUTE_SYSTEM,
3435 : check_empty_fn,
3436 : &list_count);
3437 0 : if (!NT_STATUS_IS_OK(status)) {
3438 0 : printf("cli_list of %s returned %s\n",
3439 : dname,
3440 : nt_errstr(status));
3441 0 : return false;
3442 : }
3443 0 : if (list_count != 2) {
3444 0 : printf("cli_list of %s returned a count of %u\n",
3445 : dname,
3446 : list_count);
3447 0 : return false;
3448 : }
3449 :
3450 : /* Open target directory. */
3451 0 : status = cli_ntcreate(cli,
3452 : dname,
3453 : 0,
3454 : DELETE_ACCESS|FILE_READ_DATA,
3455 : FILE_ATTRIBUTE_DIRECTORY,
3456 : FILE_SHARE_READ|
3457 : FILE_SHARE_WRITE|
3458 : FILE_SHARE_DELETE,
3459 : FILE_OPEN,
3460 : FILE_DIRECTORY_FILE,
3461 : 0,
3462 : &fnum,
3463 : NULL);
3464 0 : if (!NT_STATUS_IS_OK(status)) {
3465 0 : printf("cli_ntcreate for directory %s returned %s\n",
3466 : dname,
3467 : nt_errstr(status));
3468 0 : goto out;
3469 : }
3470 :
3471 : /* Now set the delete on close bit. */
3472 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3473 0 : if (!NT_STATUS_IS_OK(status)) {
3474 0 : printf("cli_cli_nt_delete_on_close set for directory "
3475 : "%s returned %s (should have succeeded)\n",
3476 : dname,
3477 : nt_errstr(status));
3478 0 : goto out;
3479 : }
3480 :
3481 0 : ret = true;
3482 :
3483 0 : out:
3484 :
3485 0 : if (fnum != (uint16_t)-1) {
3486 0 : (void)cli_nt_delete_on_close(cli, fnum, 0);
3487 0 : (void)cli_close(cli, fnum);
3488 : }
3489 0 : return ret;
3490 : }
3491 :
3492 : /*
3493 : * Test setting the delete on close bit on a directory
3494 : * containing an unwritable file fails or succeeds
3495 : * an a share set with "hide unwritable = yes"
3496 : * depending on the setting of "delete veto files".
3497 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3498 : *
3499 : * Second version. With "delete veto files = no"
3500 : * setting the delete on close should fail.
3501 : */
3502 :
3503 0 : bool run_delete_on_close_nonwrite_delete_no_test(int dummy)
3504 : {
3505 0 : struct cli_state *cli = NULL;
3506 : NTSTATUS status;
3507 0 : const char *dname = "delete_veto_no";
3508 0 : const char *list_dname = "delete_veto_no\\*";
3509 0 : uint16_t fnum = (uint16_t)-1;
3510 0 : bool ret = false;
3511 0 : unsigned int list_count = 0;
3512 :
3513 0 : printf("SMB2 delete on close nonwrite - delete veto yes\n");
3514 :
3515 0 : if (!torture_init_connection(&cli)) {
3516 0 : return false;
3517 : }
3518 :
3519 0 : status = smbXcli_negprot(cli->conn,
3520 0 : cli->timeout,
3521 : PROTOCOL_SMB2_02,
3522 : PROTOCOL_SMB3_11);
3523 0 : if (!NT_STATUS_IS_OK(status)) {
3524 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3525 0 : return false;
3526 : }
3527 :
3528 0 : status = cli_session_setup_creds(cli, torture_creds);
3529 0 : if (!NT_STATUS_IS_OK(status)) {
3530 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3531 0 : return false;
3532 : }
3533 :
3534 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3535 0 : if (!NT_STATUS_IS_OK(status)) {
3536 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3537 0 : return false;
3538 : }
3539 :
3540 : /* Ensure target directory is seen as empty. */
3541 0 : status = cli_list(cli,
3542 : list_dname,
3543 : FILE_ATTRIBUTE_DIRECTORY |
3544 : FILE_ATTRIBUTE_HIDDEN |
3545 : FILE_ATTRIBUTE_SYSTEM,
3546 : check_empty_fn,
3547 : &list_count);
3548 0 : if (!NT_STATUS_IS_OK(status)) {
3549 0 : printf("cli_list of %s returned %s\n",
3550 : dname,
3551 : nt_errstr(status));
3552 0 : return false;
3553 : }
3554 0 : if (list_count != 2) {
3555 0 : printf("cli_list of %s returned a count of %u\n",
3556 : dname,
3557 : list_count);
3558 0 : return false;
3559 : }
3560 :
3561 : /* Open target directory. */
3562 0 : status = cli_ntcreate(cli,
3563 : dname,
3564 : 0,
3565 : DELETE_ACCESS|FILE_READ_DATA,
3566 : FILE_ATTRIBUTE_DIRECTORY,
3567 : FILE_SHARE_READ|
3568 : FILE_SHARE_WRITE|
3569 : FILE_SHARE_DELETE,
3570 : FILE_OPEN,
3571 : FILE_DIRECTORY_FILE,
3572 : 0,
3573 : &fnum,
3574 : NULL);
3575 0 : if (!NT_STATUS_IS_OK(status)) {
3576 0 : printf("cli_ntcreate for directory %s returned %s\n",
3577 : dname,
3578 : nt_errstr(status));
3579 0 : goto out;
3580 : }
3581 :
3582 : /* Now set the delete on close bit. */
3583 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3584 0 : if (NT_STATUS_IS_OK(status)) {
3585 0 : printf("cli_cli_nt_delete_on_close set for directory "
3586 : "%s returned NT_STATUS_OK "
3587 : "(should have failed)\n",
3588 : dname);
3589 0 : goto out;
3590 : }
3591 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3592 0 : printf("cli_cli_nt_delete_on_close set for directory "
3593 : "%s returned %s "
3594 : "(should have returned "
3595 : "NT_STATUS_DIRECTORY_NOT_EMPTY)\n",
3596 : dname,
3597 : nt_errstr(status));
3598 0 : goto out;
3599 : }
3600 :
3601 0 : ret = true;
3602 :
3603 0 : out:
3604 :
3605 0 : if (fnum != (uint16_t)-1) {
3606 0 : (void)cli_nt_delete_on_close(cli, fnum, 0);
3607 0 : (void)cli_close(cli, fnum);
3608 : }
3609 0 : return ret;
3610 : }
3611 :
3612 0 : bool run_smb2_invalid_pipename(int dummy)
3613 : {
3614 0 : struct cli_state *cli = NULL;
3615 : NTSTATUS status;
3616 0 : uint64_t fid_persistent = 0;
3617 0 : uint64_t fid_volatile = 0;
3618 0 : const char *unknown_pipe = "badpipe";
3619 0 : const char *invalid_pipe = "../../../../../../../../../badpipe";
3620 :
3621 0 : printf("Starting SMB2-INVALID-PIPENAME\n");
3622 :
3623 0 : if (!torture_init_connection(&cli)) {
3624 0 : return false;
3625 : }
3626 :
3627 0 : status = smbXcli_negprot(cli->conn,
3628 0 : cli->timeout,
3629 : PROTOCOL_SMB2_02,
3630 : PROTOCOL_SMB3_11);
3631 0 : if (!NT_STATUS_IS_OK(status)) {
3632 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3633 0 : return false;
3634 : }
3635 :
3636 0 : status = cli_session_setup_creds(cli, torture_creds);
3637 0 : if (!NT_STATUS_IS_OK(status)) {
3638 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3639 0 : return false;
3640 : }
3641 :
3642 0 : status = cli_tree_connect(cli, "IPC$", "?????", NULL);
3643 0 : if (!NT_STATUS_IS_OK(status)) {
3644 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3645 0 : return false;
3646 : }
3647 :
3648 : /* Try and connect to an unknown pipename. */
3649 0 : status = smb2cli_create(cli->conn,
3650 0 : cli->timeout,
3651 0 : cli->smb2.session,
3652 0 : cli->smb2.tcon,
3653 : unknown_pipe,
3654 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3655 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3656 : SEC_STD_SYNCHRONIZE|
3657 : SEC_FILE_READ_DATA|
3658 : SEC_FILE_WRITE_DATA|
3659 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
3660 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3661 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3662 : FILE_CREATE, /* create_disposition, */
3663 : 0, /* create_options, */
3664 : NULL, /* smb2_create_blobs *blobs */
3665 : &fid_persistent,
3666 : &fid_volatile,
3667 : NULL, /* struct smb_create_returns * */
3668 : talloc_tos(), /* mem_ctx. */
3669 : NULL); /* struct smb2_create_blobs */
3670 : /* We should get NT_STATUS_OBJECT_NAME_NOT_FOUND */
3671 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3672 0 : printf("%s:%d smb2cli_create on name %s returned %s\n",
3673 : __FILE__,
3674 : __LINE__,
3675 : unknown_pipe,
3676 : nt_errstr(status));
3677 0 : return false;
3678 : }
3679 :
3680 : /* Try and connect to an invalid pipename containing unix separators. */
3681 0 : status = smb2cli_create(cli->conn,
3682 0 : cli->timeout,
3683 0 : cli->smb2.session,
3684 0 : cli->smb2.tcon,
3685 : invalid_pipe,
3686 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3687 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3688 : SEC_STD_SYNCHRONIZE|
3689 : SEC_FILE_READ_DATA|
3690 : SEC_FILE_WRITE_DATA|
3691 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
3692 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3693 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3694 : FILE_CREATE, /* create_disposition, */
3695 : 0, /* create_options, */
3696 : NULL, /* smb2_create_blobs *blobs */
3697 : &fid_persistent,
3698 : &fid_volatile,
3699 : NULL, /* struct smb_create_returns * */
3700 : talloc_tos(), /* mem_ctx. */
3701 : NULL); /* struct smb2_create_blobs */
3702 : /*
3703 : * We should still get NT_STATUS_OBJECT_NAME_NOT_FOUND
3704 : * (tested against Windows 2022).
3705 : */
3706 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3707 0 : printf("%s:%d smb2cli_create on name %s returned %s\n",
3708 : __FILE__,
3709 : __LINE__,
3710 : invalid_pipe,
3711 : nt_errstr(status));
3712 0 : return false;
3713 : }
3714 0 : return true;
3715 : }
|