LCOV - code coverage report
Current view: top level - source3/torture - test_smb2.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 224 1615 13.9 %
Date: 2024-06-13 04:01:37 Functions: 8 22 36.4 %

          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             : }

Generated by: LCOV version 1.13