LCOV - code coverage report
Current view: top level - source3/torture - test_smb2.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 1202 2282 52.7 %
Date: 2024-04-13 12:30:31 Functions: 32 34 94.1 %

          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          13 : bool run_smb2_basic(int dummy)
      38             : {
      39           0 :         struct cli_state *cli;
      40           0 :         NTSTATUS status;
      41           0 :         uint64_t fid_persistent, fid_volatile;
      42          13 :         const char *hello = "Hello, world\n";
      43           0 :         uint8_t *result;
      44           0 :         uint32_t nread;
      45           0 :         uint8_t *dir_data;
      46           0 :         uint32_t dir_data_length;
      47          13 :         uint32_t saved_tid = 0;
      48          13 :         struct smbXcli_tcon *saved_tcon = NULL;
      49          13 :         char *saved_share = NULL;
      50          13 :         uint64_t saved_uid = 0;
      51             : 
      52          13 :         printf("Starting SMB2-BASIC\n");
      53             : 
      54          13 :         if (!torture_init_connection(&cli)) {
      55           0 :                 return false;
      56             :         }
      57             : 
      58          13 :         status = smbXcli_negprot(cli->conn,
      59          13 :                                  cli->timeout,
      60             :                                  PROTOCOL_SMB2_02,
      61             :                                  PROTOCOL_SMB2_02,
      62             :                                  NULL,
      63             :                                  NULL,
      64             :                                  NULL);
      65          13 :         if (!NT_STATUS_IS_OK(status)) {
      66           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
      67           0 :                 return false;
      68             :         }
      69             : 
      70          13 :         status = cli_session_setup_creds(cli, torture_creds);
      71          13 :         if (!NT_STATUS_IS_OK(status)) {
      72           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
      73           0 :                 return false;
      74             :         }
      75             : 
      76          13 :         status = cli_tree_connect(cli, share, "?????", NULL);
      77          13 :         if (!NT_STATUS_IS_OK(status)) {
      78           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
      79           0 :                 return false;
      80             :         }
      81             : 
      82          13 :         status = smb2cli_create(
      83          13 :                 cli->conn,
      84          13 :                 cli->timeout,
      85          13 :                 cli->smb2.session,
      86          13 :                 cli->smb2.tcon,
      87             :                 "smb2-basic.txt",
      88             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
      89             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
      90             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
      91             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
      92             :                 FILE_SHARE_READ|
      93             :                 FILE_SHARE_WRITE|
      94             :                 FILE_SHARE_DELETE, /* share_access, */
      95             :                 FILE_CREATE, /* create_disposition, */
      96             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
      97             :                 NULL, /* smb2_create_blobs *blobs */
      98             :                 &fid_persistent,
      99             :                 &fid_volatile,
     100             :                 NULL,
     101             :                 NULL,
     102             :                 NULL,
     103             :                 NULL);
     104          13 :         if (!NT_STATUS_IS_OK(status)) {
     105           0 :                 printf("smb2cli_create returned %s\n", nt_errstr(status));
     106           0 :                 return false;
     107             :         }
     108             : 
     109          13 :         status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
     110          13 :                                cli->smb2.tcon, strlen(hello), 0, fid_persistent,
     111             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     112          13 :         if (!NT_STATUS_IS_OK(status)) {
     113           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     114           0 :                 return false;
     115             :         }
     116             : 
     117          13 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
     118          13 :                                cli->smb2.tcon, fid_persistent, fid_volatile);
     119          13 :         if (!NT_STATUS_IS_OK(status)) {
     120           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     121           0 :                 return false;
     122             :         }
     123             : 
     124          13 :         status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
     125          13 :                               cli->smb2.tcon, 0x10000, 0, fid_persistent,
     126             :                               fid_volatile, 2, 0,
     127             :                               talloc_tos(), &result, &nread);
     128          13 :         if (!NT_STATUS_IS_OK(status)) {
     129           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     130           0 :                 return false;
     131             :         }
     132             : 
     133          13 :         if (nread != strlen(hello)) {
     134           0 :                 printf("smb2cli_read returned %d bytes, expected %d\n",
     135           0 :                        (int)nread, (int)strlen(hello));
     136           0 :                 return false;
     137             :         }
     138             : 
     139          13 :         if (memcmp(hello, result, nread) != 0) {
     140           0 :                 printf("smb2cli_read returned '%s', expected '%s'\n",
     141             :                        result, hello);
     142           0 :                 return false;
     143             :         }
     144             : 
     145          13 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
     146          13 :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
     147          13 :         if (!NT_STATUS_IS_OK(status)) {
     148           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
     149           0 :                 return false;
     150             :         }
     151             : 
     152          13 :         status = smb2cli_create(
     153          13 :                 cli->conn,
     154          13 :                 cli->timeout,
     155          13 :                 cli->smb2.session,
     156          13 :                 cli->smb2.tcon,
     157             :                 "",
     158             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     159             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     160             :                 SEC_STD_SYNCHRONIZE|
     161             :                 SEC_DIR_LIST|
     162             :                 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
     163             :                 0, /* file_attributes, */
     164             :                 FILE_SHARE_READ|
     165             :                 FILE_SHARE_WRITE|
     166             :                 FILE_SHARE_DELETE, /* share_access, */
     167             :                 FILE_OPEN, /* create_disposition, */
     168             :                 FILE_SYNCHRONOUS_IO_NONALERT|
     169             :                 FILE_DIRECTORY_FILE, /* create_options, */
     170             :                 NULL, /* smb2_create_blobs *blobs */
     171             :                 &fid_persistent,
     172             :                 &fid_volatile,
     173             :                 NULL,
     174             :                 NULL,
     175             :                 NULL,
     176             :                 NULL);
     177          13 :         if (!NT_STATUS_IS_OK(status)) {
     178           0 :                 printf("smb2cli_create returned %s\n", nt_errstr(status));
     179           0 :                 return false;
     180             :         }
     181             : 
     182          13 :         status = smb2cli_query_directory(
     183          13 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
     184             :                 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
     185             :                 talloc_tos(), &dir_data, &dir_data_length);
     186             : 
     187          13 :         if (!NT_STATUS_IS_OK(status)) {
     188           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
     189           0 :                 return false;
     190             :         }
     191             : 
     192          13 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
     193          13 :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
     194          13 :         if (!NT_STATUS_IS_OK(status)) {
     195           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
     196           0 :                 return false;
     197             :         }
     198             : 
     199          13 :         saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
     200          13 :         cli_state_save_tcon_share(cli, &saved_tcon, &saved_share);
     201          13 :         cli->smb2.tcon = smbXcli_tcon_create(cli);
     202          13 :         smb2cli_tcon_set_values(cli->smb2.tcon,
     203             :                                 NULL, /* session */
     204             :                                 saved_tid,
     205             :                                 0, /* type */
     206             :                                 0, /* flags */
     207             :                                 0, /* capabilities */
     208             :                                 0  /* maximal_access */);
     209          13 :         status = smb2cli_tdis(cli->conn,
     210          13 :                               cli->timeout,
     211          13 :                               cli->smb2.session,
     212          13 :                               cli->smb2.tcon);
     213          13 :         cli_state_restore_tcon_share(cli, saved_tcon, saved_share);
     214          13 :         if (!NT_STATUS_IS_OK(status)) {
     215           0 :                 printf("smb2cli_tdis returned %s\n", nt_errstr(status));
     216           0 :                 return false;
     217             :         }
     218             : 
     219          13 :         status = smb2cli_tdis(cli->conn,
     220          13 :                               cli->timeout,
     221          13 :                               cli->smb2.session,
     222          13 :                               cli->smb2.tcon);
     223          13 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
     224           0 :                 printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
     225           0 :                 return false;
     226             :         }
     227             : 
     228          13 :         saved_uid = smb2cli_session_current_id(cli->smb2.session);
     229          13 :         status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
     230          13 :         if (!NT_STATUS_IS_OK(status)) {
     231           0 :                 printf("smb2cli_logoff returned %s\n", nt_errstr(status));
     232           0 :                 return false;
     233             :         }
     234             : 
     235          13 :         cli->smb2.session = smbXcli_session_create(cli, cli->conn);
     236          13 :         if (cli->smb2.session == NULL) {
     237           0 :                 printf("smbXcli_session_create() returned NULL\n");
     238           0 :                 return false;
     239             :         }
     240             : 
     241          13 :         smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
     242             : 
     243          13 :         status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
     244          13 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
     245           0 :                 printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
     246           0 :                 return false;
     247             :         }
     248             : 
     249          13 :         return true;
     250             : }
     251             : 
     252           4 : bool run_smb2_negprot(int dummy)
     253             : {
     254           0 :         struct cli_state *cli;
     255           0 :         NTSTATUS status;
     256           0 :         enum protocol_types protocol;
     257           4 :         const char *name = NULL;
     258             : 
     259           4 :         printf("Starting SMB2-NEGPROT\n");
     260             : 
     261           4 :         if (!torture_init_connection(&cli)) {
     262           0 :                 return false;
     263             :         }
     264             : 
     265           4 :         status = smbXcli_negprot(cli->conn,
     266           4 :                                  cli->timeout,
     267             :                                  PROTOCOL_CORE,
     268             :                                  PROTOCOL_LATEST,
     269             :                                  NULL,
     270             :                                  NULL,
     271             :                                  NULL);
     272           4 :         if (!NT_STATUS_IS_OK(status)) {
     273           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     274           0 :                 return false;
     275             :         }
     276             : 
     277           4 :         protocol = smbXcli_conn_protocol(cli->conn);
     278           4 :         name = smb_protocol_types_string(protocol);
     279             : 
     280           4 :         if (protocol >= PROTOCOL_SMB2_02) {
     281           4 :                 printf("Server supports %s\n", name);
     282             :         } else {
     283           0 :                 printf("Server DOES NOT support SMB2, only %s\n", name);
     284           0 :                 return false;
     285             :         }
     286             : 
     287           4 :         status = smbXcli_negprot(cli->conn,
     288           4 :                                  cli->timeout,
     289             :                                  protocol,
     290             :                                  protocol,
     291             :                                  NULL,
     292             :                                  NULL,
     293             :                                  NULL);
     294           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
     295           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
     296           0 :             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
     297           0 :                 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
     298             :                         nt_errstr(status));
     299           0 :                 return false;
     300             :         }
     301             : 
     302           4 :         if (smbXcli_conn_is_connected(cli->conn)) {
     303           0 :                 printf("2nd smbXcli_negprot should disconnect "
     304             :                        "- still connected\n");
     305           0 :                 return false;
     306             :         }
     307             : 
     308           4 :         return true;
     309             : }
     310             : 
     311           5 : bool run_smb2_anonymous(int dummy)
     312             : {
     313           5 :         struct cli_state *cli = NULL;
     314           0 :         NTSTATUS status;
     315           5 :         struct cli_credentials *anon_creds = NULL;
     316           5 :         bool guest = false;
     317             : 
     318           5 :         printf("Starting SMB2-ANONYMOUS\n");
     319             : 
     320           5 :         if (!torture_init_connection(&cli)) {
     321           0 :                 return false;
     322             :         }
     323             : 
     324           5 :         status = smbXcli_negprot(cli->conn,
     325           5 :                                  cli->timeout,
     326             :                                  PROTOCOL_SMB2_02,
     327             :                                  PROTOCOL_LATEST,
     328             :                                  NULL,
     329             :                                  NULL,
     330             :                                  NULL);
     331           5 :         if (!NT_STATUS_IS_OK(status)) {
     332           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     333           0 :                 return false;
     334             :         }
     335             : 
     336           5 :         anon_creds = cli_credentials_init_anon(talloc_tos());
     337           5 :         if (anon_creds == NULL) {
     338           0 :                 printf("cli_credentials_init_anon failed\n");
     339           0 :                 return false;
     340             :         }
     341             : 
     342           5 :         status = cli_session_setup_creds(cli, anon_creds);
     343           5 :         if (!NT_STATUS_IS_OK(status)) {
     344           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
     345           0 :                 return false;
     346             :         }
     347             : 
     348           5 :         guest = smbXcli_session_is_guest(cli->smb2.session);
     349           5 :         if (guest) {
     350           0 :                 printf("anonymous session should not have guest authentication\n");
     351           0 :                 return false;
     352             :         }
     353             : 
     354           5 :         return true;
     355             : }
     356             : 
     357           4 : bool run_smb2_session_reconnect(int dummy)
     358             : {
     359           0 :         struct cli_state *cli1;
     360           0 :         struct cli_state *cli2;
     361           0 :         NTSTATUS status;
     362           0 :         bool ok;
     363           0 :         uint64_t fid_persistent, fid_volatile;
     364           0 :         struct tevent_context *ev;
     365           0 :         struct tevent_req *subreq;
     366           4 :         DATA_BLOB in_blob = data_blob_null;
     367           0 :         DATA_BLOB out_blob;
     368           0 :         DATA_BLOB session_key;
     369           0 :         struct auth_generic_state *auth_generic_state;
     370           0 :         struct iovec *recv_iov;
     371           4 :         const char *hello = "Hello, world\n";
     372           0 :         uint8_t *result;
     373           0 :         uint32_t nread;
     374             : 
     375           4 :         printf("Starting SMB2-SESSION-RECONNECT\n");
     376             : 
     377           4 :         if (!torture_init_connection(&cli1)) {
     378           0 :                 return false;
     379             :         }
     380             : 
     381           4 :         status = smbXcli_negprot(cli1->conn,
     382           4 :                                  cli1->timeout,
     383             :                                  PROTOCOL_SMB2_02,
     384             :                                  PROTOCOL_LATEST,
     385             :                                  NULL,
     386             :                                  NULL,
     387             :                                  NULL);
     388           4 :         if (!NT_STATUS_IS_OK(status)) {
     389           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     390           0 :                 return false;
     391             :         }
     392             : 
     393           4 :         status = cli_session_setup_creds(cli1, torture_creds);
     394           4 :         if (!NT_STATUS_IS_OK(status)) {
     395           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
     396           0 :                 return false;
     397             :         }
     398             : 
     399           4 :         status = cli_tree_connect(cli1, share, "?????", NULL);
     400           4 :         if (!NT_STATUS_IS_OK(status)) {
     401           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
     402           0 :                 return false;
     403             :         }
     404             : 
     405           4 :         status = smb2cli_create(
     406           4 :                 cli1->conn,
     407           4 :                 cli1->timeout,
     408           4 :                 cli1->smb2.session,
     409           4 :                 cli1->smb2.tcon,
     410             :                 "session-reconnect.txt",
     411             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     412             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     413             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
     414             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
     415             :                 FILE_SHARE_READ|
     416             :                 FILE_SHARE_WRITE|
     417             :                 FILE_SHARE_DELETE, /* share_access, */
     418             :                 FILE_CREATE, /* create_disposition, */
     419             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
     420             :                 NULL, /* smb2_create_blobs *blobs */
     421             :                 &fid_persistent,
     422             :                 &fid_volatile,
     423             :                 NULL,
     424             :                 NULL,
     425             :                 NULL,
     426             :                 NULL);
     427           4 :         if (!NT_STATUS_IS_OK(status)) {
     428           0 :                 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
     429           0 :                 return false;
     430             :         }
     431             : 
     432           4 :         status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
     433           4 :                                cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
     434             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     435           4 :         if (!NT_STATUS_IS_OK(status)) {
     436           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     437           0 :                 return false;
     438             :         }
     439             : 
     440           4 :         status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
     441           4 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
     442           4 :         if (!NT_STATUS_IS_OK(status)) {
     443           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     444           0 :                 return false;
     445             :         }
     446             : 
     447           4 :         status = smb2cli_read(cli1->conn, cli1->timeout, cli1->smb2.session,
     448           4 :                               cli1->smb2.tcon, 0x10000, 0, fid_persistent,
     449             :                               fid_volatile, 2, 0,
     450             :                               talloc_tos(), &result, &nread);
     451           4 :         if (!NT_STATUS_IS_OK(status)) {
     452           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     453           0 :                 return false;
     454             :         }
     455             : 
     456           4 :         if (nread != strlen(hello)) {
     457           0 :                 printf("smb2cli_read returned %d bytes, expected %d\n",
     458           0 :                        (int)nread, (int)strlen(hello));
     459           0 :                 return false;
     460             :         }
     461             : 
     462           4 :         if (memcmp(hello, result, nread) != 0) {
     463           0 :                 printf("smb2cli_read returned '%s', expected '%s'\n",
     464             :                        result, hello);
     465           0 :                 return false;
     466             :         }
     467             : 
     468             :         /* prepare second session */
     469             : 
     470           4 :         if (!torture_init_connection(&cli2)) {
     471           0 :                 return false;
     472             :         }
     473             : 
     474           4 :         status = smbXcli_negprot(cli2->conn,
     475           4 :                                  cli2->timeout,
     476             :                                  PROTOCOL_SMB2_02,
     477             :                                  PROTOCOL_LATEST,
     478             :                                  NULL,
     479             :                                  NULL,
     480             :                                  NULL);
     481           4 :         if (!NT_STATUS_IS_OK(status)) {
     482           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     483           0 :                 return false;
     484             :         }
     485             : 
     486           4 :         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
     487           4 :         if (!NT_STATUS_IS_OK(status)) {
     488           0 :                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
     489           0 :                 return false;
     490             :         }
     491             : 
     492           4 :         gensec_want_feature(auth_generic_state->gensec_security,
     493             :                             GENSEC_FEATURE_SESSION_KEY);
     494             : 
     495           4 :         status = auth_generic_set_creds(auth_generic_state, torture_creds);
     496           4 :         if (!NT_STATUS_IS_OK(status)) {
     497           0 :                 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
     498           0 :                 return false;
     499             :         }
     500             : 
     501           4 :         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
     502           4 :         if (!NT_STATUS_IS_OK(status)) {
     503           0 :                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
     504           0 :                 return false;
     505             :         }
     506             : 
     507           4 :         ev = samba_tevent_context_init(talloc_tos());
     508           4 :         if (ev == NULL) {
     509           0 :                 printf("samba_tevent_context_init() returned NULL\n");
     510           0 :                 return false;
     511             :         }
     512             : 
     513           4 :         status = gensec_update(auth_generic_state->gensec_security,
     514             :                                talloc_tos(), data_blob_null, &in_blob);
     515           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     516           0 :                 printf("gensec_update returned %s\n", nt_errstr(status));
     517           0 :                 return false;
     518             :         }
     519             : 
     520           4 :         cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
     521             : 
     522           4 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
     523           4 :                                             cli2->conn,
     524           4 :                                             cli2->timeout,
     525           4 :                                             cli2->smb2.session,
     526             :                                             0x0, /* in_flags */
     527             :                                             SMB2_CAP_DFS, /* in_capabilities */
     528             :                                             0, /* in_channel */
     529             :                                             /* in_previous_session_id: */
     530           4 :                                             smb2cli_session_current_id(cli1->smb2.session),
     531             :                                             &in_blob); /* in_security_buffer */
     532           4 :         if (subreq == NULL) {
     533           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
     534           0 :                 return false;
     535             :         }
     536             : 
     537           4 :         ok = tevent_req_poll(subreq, ev);
     538           4 :         if (!ok) {
     539           0 :                 printf("tevent_req_poll() returned false\n");
     540           0 :                 return false;
     541             :         }
     542             : 
     543           4 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
     544             :                                             NULL, &out_blob);
     545           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     546           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
     547             :                         nt_errstr(status));
     548           0 :                 return false;
     549             :         }
     550             : 
     551           4 :         status = gensec_update(auth_generic_state->gensec_security,
     552             :                                talloc_tos(), out_blob, &in_blob);
     553           4 :         if (!NT_STATUS_IS_OK(status)) {
     554           0 :                 printf("auth_generic_update returned %s\n", nt_errstr(status));
     555           0 :                 return false;
     556             :         }
     557             : 
     558           4 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
     559           4 :                                             cli2->conn,
     560           4 :                                             cli2->timeout,
     561           4 :                                             cli2->smb2.session,
     562             :                                             0x0, /* in_flags */
     563             :                                             SMB2_CAP_DFS, /* in_capabilities */
     564             :                                             0, /* in_channel */
     565             :                                             /* in_previous_session_id: */
     566           4 :                                             smb2cli_session_current_id(cli1->smb2.session),
     567             :                                             &in_blob); /* in_security_buffer */
     568           4 :         if (subreq == NULL) {
     569           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
     570           0 :                 return false;
     571             :         }
     572             : 
     573           4 :         ok = tevent_req_poll(subreq, ev);
     574           4 :         if (!ok) {
     575           0 :                 printf("tevent_req_poll() returned false\n");
     576           0 :                 return false;
     577             :         }
     578             : 
     579           4 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
     580             :                                             &recv_iov, &out_blob);
     581           4 :         if (!NT_STATUS_IS_OK(status)) {
     582           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
     583             :                         nt_errstr(status));
     584           0 :                 return false;
     585             :         }
     586             : 
     587           4 :         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
     588             :                                     &session_key);
     589           4 :         if (!NT_STATUS_IS_OK(status)) {
     590           0 :                 printf("gensec_session_key returned %s\n",
     591             :                         nt_errstr(status));
     592           0 :                 return false;
     593             :         }
     594             : 
     595             :         /* check file operation on the old client */
     596             : 
     597           4 :         status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
     598           4 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
     599           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
     600           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     601           0 :                 return false;
     602             :         }
     603             : 
     604           4 :         status = cli_tree_connect(cli1, share, "?????", NULL);
     605           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
     606           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
     607           0 :                 return false;
     608             :         }
     609             : 
     610             :         /*
     611             :          * checking file operations without signing.
     612             :          * on w2k8r2 at least, flush, read and write also work the same way,
     613             :          * while create gives ACCESS_DENIED without signing
     614             :          */
     615           4 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
     616           4 :                                cli2->smb2.tcon, fid_persistent, fid_volatile);
     617           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     618           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     619             :         {
     620           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     621           0 :                 return false;
     622             :         }
     623             : 
     624           4 :         status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
     625           4 :                                cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
     626             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     627           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     628           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     629             :         {
     630           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     631           0 :                 return false;
     632             :         }
     633             : 
     634           4 :         status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
     635           4 :                               cli2->smb2.tcon, 0x10000, 0, fid_persistent,
     636             :                               fid_volatile, 2, 0,
     637             :                               talloc_tos(), &result, &nread);
     638           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     639           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     640             :         {
     641           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     642           0 :                 return false;
     643             :         }
     644             : 
     645           4 :         status = smb2cli_create(
     646           4 :                 cli2->conn,
     647           4 :                 cli2->timeout,
     648           4 :                 cli2->smb2.session,
     649           4 :                 cli2->smb2.tcon,
     650             :                 "session-reconnect.txt",
     651             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     652             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     653             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
     654             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
     655             :                 FILE_SHARE_READ|
     656             :                 FILE_SHARE_WRITE|
     657             :                 FILE_SHARE_DELETE, /* share_access, */
     658             :                 FILE_CREATE, /* create_disposition, */
     659             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
     660             :                 NULL, /* smb2_create_blobs *blobs */
     661             :                 &fid_persistent,
     662             :                 &fid_volatile,
     663             :                 NULL,
     664             :                 NULL,
     665             :                 NULL,
     666             :                 NULL);
     667           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
     668           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
     669           0 :                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
     670           0 :                 return false;
     671             :         }
     672             : 
     673             :         /* now grab the session key and try with signing */
     674             : 
     675           4 :         status = smb2cli_session_set_session_key(cli2->smb2.session,
     676             :                                                  session_key,
     677             :                                                  recv_iov);
     678           4 :         if (!NT_STATUS_IS_OK(status)) {
     679           0 :                 printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
     680           0 :                 return false;
     681             :         }
     682             : 
     683             :         /* the tid seems to be irrelevant at this stage */
     684             : 
     685           4 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
     686           4 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
     687           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     688           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     689             :         {
     690           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     691           0 :                 return false;
     692             :         }
     693             : 
     694           4 :         status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
     695           4 :                                cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
     696             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     697           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     698           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     699             :         {
     700           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     701           0 :                 return false;
     702             :         }
     703             : 
     704           4 :         status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
     705           4 :                               cli1->smb2.tcon, 0x10000, 0, fid_persistent,
     706             :                               fid_volatile, 2, 0,
     707             :                               talloc_tos(), &result, &nread);
     708           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
     709           4 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     710             :         {
     711           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     712           0 :                 return false;
     713             :         }
     714             : 
     715           4 :         status = smb2cli_create(
     716           4 :                 cli2->conn,
     717           4 :                 cli2->timeout,
     718           4 :                 cli2->smb2.session,
     719           4 :                 cli1->smb2.tcon,
     720             :                 "session-reconnect.txt",
     721             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     722             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     723             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
     724             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
     725             :                 FILE_SHARE_READ|
     726             :                 FILE_SHARE_WRITE|
     727             :                 FILE_SHARE_DELETE, /* share_access, */
     728             :                 FILE_CREATE, /* create_disposition, */
     729             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
     730             :                 NULL, /* smb2_create_blobs *blobs */
     731             :                 &fid_persistent,
     732             :                 &fid_volatile,
     733             :                 NULL,
     734             :                 NULL,
     735             :                 NULL,
     736             :                 NULL);
     737           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) &&
     738           0 :             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
     739             :         {
     740           0 :                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
     741           0 :                 return false;
     742             :         }
     743             : 
     744             :         /* now do a new tcon and test file calls again */
     745             : 
     746           4 :         status = cli_tree_connect(cli2, share, "?????", NULL);
     747           4 :         if (!NT_STATUS_IS_OK(status)) {
     748           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
     749           0 :                 return false;
     750             :         }
     751             : 
     752           4 :         status = smb2cli_create(
     753           4 :                 cli2->conn,
     754           4 :                 cli2->timeout,
     755           4 :                 cli2->smb2.session,
     756           4 :                 cli2->smb2.tcon,
     757             :                 "session-reconnect.txt",
     758             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     759             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     760             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
     761             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
     762             :                 FILE_SHARE_READ|
     763             :                 FILE_SHARE_WRITE|
     764             :                 FILE_SHARE_DELETE, /* share_access, */
     765             :                 FILE_CREATE, /* create_disposition, */
     766             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
     767             :                 NULL, /* smb2_create_blobs *blobs */
     768             :                 &fid_persistent,
     769             :                 &fid_volatile,
     770             :                 NULL,
     771             :                 NULL,
     772             :                 NULL,
     773             :                 NULL);
     774           4 :         if (!NT_STATUS_IS_OK(status)) {
     775           0 :                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
     776           0 :                 return false;
     777             :         }
     778             : 
     779           4 :         status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
     780           4 :                                cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
     781             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     782           4 :         if (!NT_STATUS_IS_OK(status)) {
     783           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     784           0 :                 return false;
     785             :         }
     786             : 
     787           4 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
     788           4 :                                cli2->smb2.tcon, fid_persistent, fid_volatile);
     789           4 :         if (!NT_STATUS_IS_OK(status)) {
     790           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     791           0 :                 return false;
     792             :         }
     793             : 
     794           4 :         status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
     795           4 :                               cli2->smb2.tcon, 0x10000, 0, fid_persistent,
     796             :                               fid_volatile, 2, 0,
     797             :                               talloc_tos(), &result, &nread);
     798           4 :         if (!NT_STATUS_IS_OK(status)) {
     799           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     800           0 :                 return false;
     801             :         }
     802             : 
     803           4 :         if (nread != strlen(hello)) {
     804           0 :                 printf("smb2cli_read returned %d bytes, expected %d\n",
     805           0 :                        (int)nread, (int)strlen(hello));
     806           0 :                 return false;
     807             :         }
     808             : 
     809           4 :         if (memcmp(hello, result, nread) != 0) {
     810           0 :                 printf("smb2cli_read returned '%s', expected '%s'\n",
     811             :                        result, hello);
     812           0 :                 return false;
     813             :         }
     814             : 
     815           4 :         return true;
     816             : }
     817             : 
     818           0 : bool run_smb2_tcon_dependence(int dummy)
     819             : {
     820           0 :         struct cli_state *cli;
     821           0 :         NTSTATUS status;
     822           0 :         uint64_t fid_persistent, fid_volatile;
     823           0 :         const char *hello = "Hello, world\n";
     824           0 :         uint8_t *result;
     825           0 :         uint32_t nread;
     826           0 :         struct smbXcli_tcon *tcon2;
     827           0 :         uint32_t tcon2_id;
     828             : 
     829           0 :         printf("Starting SMB2-TCON-DEPENDENCE\n");
     830             : 
     831           0 :         if (!torture_init_connection(&cli)) {
     832           0 :                 return false;
     833             :         }
     834             : 
     835           0 :         status = smbXcli_negprot(cli->conn,
     836           0 :                                  cli->timeout,
     837             :                                  PROTOCOL_SMB2_02,
     838             :                                  PROTOCOL_LATEST,
     839             :                                  NULL,
     840             :                                  NULL,
     841             :                                  NULL);
     842           0 :         if (!NT_STATUS_IS_OK(status)) {
     843           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     844           0 :                 return false;
     845             :         }
     846             : 
     847           0 :         status = cli_session_setup_creds(cli, torture_creds);
     848           0 :         if (!NT_STATUS_IS_OK(status)) {
     849           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
     850           0 :                 return false;
     851             :         }
     852             : 
     853           0 :         status = cli_tree_connect(cli, share, "?????", NULL);
     854           0 :         if (!NT_STATUS_IS_OK(status)) {
     855           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
     856           0 :                 return false;
     857             :         }
     858             : 
     859           0 :         status = smb2cli_create(
     860           0 :                 cli->conn,
     861           0 :                 cli->timeout,
     862           0 :                 cli->smb2.session,
     863           0 :                 cli->smb2.tcon,
     864             :                 "tcon_depedence.txt",
     865             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
     866             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
     867             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
     868             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
     869             :                 FILE_SHARE_READ|
     870             :                 FILE_SHARE_WRITE|
     871             :                 FILE_SHARE_DELETE, /* share_access, */
     872             :                 FILE_CREATE, /* create_disposition, */
     873             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
     874             :                 NULL, /* smb2_create_blobs *blobs */
     875             :                 &fid_persistent,
     876             :                 &fid_volatile,
     877             :                 NULL,
     878             :                 NULL,
     879             :                 NULL,
     880             :                 NULL);
     881           0 :         if (!NT_STATUS_IS_OK(status)) {
     882           0 :                 printf("smb2cli_create on cli %s\n", nt_errstr(status));
     883           0 :                 return false;
     884             :         }
     885             : 
     886           0 :         status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
     887           0 :                                cli->smb2.tcon, strlen(hello), 0, fid_persistent,
     888             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
     889           0 :         if (!NT_STATUS_IS_OK(status)) {
     890           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
     891           0 :                 return false;
     892             :         }
     893             : 
     894           0 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
     895           0 :                                cli->smb2.tcon, fid_persistent, fid_volatile);
     896           0 :         if (!NT_STATUS_IS_OK(status)) {
     897           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
     898           0 :                 return false;
     899             :         }
     900             : 
     901           0 :         status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
     902           0 :                               cli->smb2.tcon, 0x10000, 0, fid_persistent,
     903             :                               fid_volatile, 2, 0,
     904             :                               talloc_tos(), &result, &nread);
     905           0 :         if (!NT_STATUS_IS_OK(status)) {
     906           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     907           0 :                 return false;
     908             :         }
     909             : 
     910           0 :         if (nread != strlen(hello)) {
     911           0 :                 printf("smb2cli_read returned %d bytes, expected %d\n",
     912           0 :                        (int)nread, (int)strlen(hello));
     913           0 :                 return false;
     914             :         }
     915             : 
     916           0 :         if (memcmp(hello, result, nread) != 0) {
     917           0 :                 printf("smb2cli_read returned '%s', expected '%s'\n",
     918             :                        result, hello);
     919           0 :                 return false;
     920             :         }
     921             : 
     922             :         /* check behaviour with wrong tid... */
     923             : 
     924           0 :         tcon2 = smbXcli_tcon_create(cli);
     925           0 :         tcon2_id = smb2cli_tcon_current_id(cli->smb2.tcon);
     926           0 :         tcon2_id++;
     927           0 :         smb2cli_tcon_set_values(tcon2,
     928             :                                 NULL, /* session */
     929             :                                 tcon2_id,
     930             :                                 0, /* type */
     931             :                                 0, /* flags */
     932             :                                 0, /* capabilities */
     933             :                                 0  /* maximal_access */);
     934             : 
     935           0 :         status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
     936             :                               tcon2, 0x10000, 0, fid_persistent,
     937             :                               fid_volatile, 2, 0,
     938             :                               talloc_tos(), &result, &nread);
     939           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
     940           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
     941           0 :                 return false;
     942             :         }
     943             : 
     944           0 :         talloc_free(tcon2);
     945             : 
     946           0 :         return true;
     947             : }
     948             : 
     949           0 : bool run_smb2_multi_channel(int dummy)
     950             : {
     951           0 :         struct cli_state *cli1;
     952           0 :         struct cli_state *cli2;
     953           0 :         struct cli_state *cli3;
     954           0 :         NTSTATUS status;
     955           0 :         bool ok;
     956           0 :         uint64_t fid_persistent, fid_volatile;
     957           0 :         struct tevent_context *ev;
     958           0 :         struct tevent_req *subreq;
     959           0 :         DATA_BLOB in_blob = data_blob_null;
     960           0 :         DATA_BLOB out_blob;
     961           0 :         DATA_BLOB channel_session_key;
     962           0 :         struct auth_generic_state *auth_generic_state;
     963           0 :         struct iovec *recv_iov;
     964           0 :         const char *hello = "Hello, world\n";
     965           0 :         uint8_t *result;
     966           0 :         uint32_t nread;
     967           0 :         struct GUID saved_guid = cli_state_client_guid;
     968             : 
     969           0 :         printf("Starting SMB2-MULTI-CHANNEL\n");
     970             : 
     971           0 :         cli_state_client_guid = GUID_random();
     972             : 
     973           0 :         if (!torture_init_connection(&cli1)) {
     974           0 :                 return false;
     975             :         }
     976             : 
     977           0 :         if (!torture_init_connection(&cli2)) {
     978           0 :                 return false;
     979             :         }
     980             : 
     981           0 :         if (!torture_init_connection(&cli3)) {
     982           0 :                 return false;
     983             :         }
     984             : 
     985           0 :         cli_state_client_guid = saved_guid;
     986             : 
     987           0 :         status = smbXcli_negprot(cli1->conn,
     988           0 :                                  cli1->timeout,
     989             :                                  PROTOCOL_SMB3_00,
     990             :                                  PROTOCOL_LATEST,
     991             :                                  NULL,
     992             :                                  NULL,
     993             :                                  NULL);
     994           0 :         if (!NT_STATUS_IS_OK(status)) {
     995           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     996           0 :                 return false;
     997             :         }
     998             : 
     999           0 :         status = smbXcli_negprot(cli2->conn,
    1000           0 :                                  cli2->timeout,
    1001             :                                  PROTOCOL_SMB3_00,
    1002             :                                  PROTOCOL_LATEST,
    1003             :                                  NULL,
    1004             :                                  NULL,
    1005             :                                  NULL);
    1006           0 :         if (!NT_STATUS_IS_OK(status)) {
    1007           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    1008           0 :                 return false;
    1009             :         }
    1010             : 
    1011           0 :         status = smbXcli_negprot(cli3->conn,
    1012           0 :                                  cli3->timeout,
    1013             :                                  PROTOCOL_SMB3_00,
    1014             :                                  PROTOCOL_LATEST,
    1015             :                                  NULL,
    1016             :                                  NULL,
    1017             :                                  NULL);
    1018           0 :         if (!NT_STATUS_IS_OK(status)) {
    1019           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    1020           0 :                 return false;
    1021             :         }
    1022             : 
    1023           0 :         status = cli_session_setup_creds(cli1, torture_creds);
    1024           0 :         if (!NT_STATUS_IS_OK(status)) {
    1025           0 :                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
    1026           0 :                 return false;
    1027             :         }
    1028             : 
    1029           0 :         status = cli_tree_connect(cli1, share, "?????", NULL);
    1030           0 :         if (!NT_STATUS_IS_OK(status)) {
    1031           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    1032           0 :                 return false;
    1033             :         }
    1034             : 
    1035           0 :         status = smb2cli_session_create_channel(cli2,
    1036           0 :                                                 cli1->smb2.session,
    1037           0 :                                                 cli2->conn,
    1038           0 :                                                 &cli2->smb2.session);
    1039           0 :         if (!NT_STATUS_IS_OK(status)) {
    1040           0 :                 printf("smb2cli_session_create_channel returned %s\n",
    1041             :                         nt_errstr(status));
    1042           0 :                 return false;
    1043             :         }
    1044             : 
    1045           0 :         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
    1046           0 :         if (!NT_STATUS_IS_OK(status)) {
    1047           0 :                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
    1048           0 :                 return false;
    1049             :         }
    1050             : 
    1051           0 :         gensec_want_feature(auth_generic_state->gensec_security,
    1052             :                             GENSEC_FEATURE_SESSION_KEY);
    1053             : 
    1054           0 :         status = auth_generic_set_creds(auth_generic_state, torture_creds);
    1055           0 :         if (!NT_STATUS_IS_OK(status)) {
    1056           0 :                 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
    1057           0 :                 return false;
    1058             :         }
    1059             : 
    1060           0 :         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
    1061           0 :         if (!NT_STATUS_IS_OK(status)) {
    1062           0 :                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
    1063           0 :                 return false;
    1064             :         }
    1065             : 
    1066           0 :         ev = samba_tevent_context_init(talloc_tos());
    1067           0 :         if (ev == NULL) {
    1068           0 :                 printf("samba_tevent_context_init() returned NULL\n");
    1069           0 :                 return false;
    1070             :         }
    1071             : 
    1072           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1073             :                                talloc_tos(), data_blob_null, &in_blob);
    1074           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1075           0 :                 printf("gensec_update returned %s\n", nt_errstr(status));
    1076           0 :                 return false;
    1077             :         }
    1078             : 
    1079           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1080           0 :                                             cli2->conn,
    1081           0 :                                             cli2->timeout,
    1082           0 :                                             cli2->smb2.session,
    1083             :                                             0x01, /* in_flags */
    1084             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1085             :                                             0, /* in_channel */
    1086             :                                             0, /* in_previous_session_id */
    1087             :                                             &in_blob); /* in_security_buffer */
    1088           0 :         if (subreq == NULL) {
    1089           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1090           0 :                 return false;
    1091             :         }
    1092             : 
    1093           0 :         ok = tevent_req_poll(subreq, ev);
    1094           0 :         if (!ok) {
    1095           0 :                 printf("tevent_req_poll() returned false\n");
    1096           0 :                 return false;
    1097             :         }
    1098             : 
    1099           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1100             :                                             NULL, &out_blob);
    1101           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1102           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1103             :                         nt_errstr(status));
    1104           0 :                 return false;
    1105             :         }
    1106             : 
    1107           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1108             :                                talloc_tos(), out_blob, &in_blob);
    1109           0 :         if (!NT_STATUS_IS_OK(status)) {
    1110           0 :                 printf("auth_generic_update returned %s\n", nt_errstr(status));
    1111           0 :                 return false;
    1112             :         }
    1113             : 
    1114           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1115           0 :                                             cli2->conn,
    1116           0 :                                             cli2->timeout,
    1117           0 :                                             cli2->smb2.session,
    1118             :                                             0x01, /* in_flags */
    1119             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1120             :                                             0, /* in_channel */
    1121             :                                             0, /* in_previous_session_id */
    1122             :                                             &in_blob); /* in_security_buffer */
    1123           0 :         if (subreq == NULL) {
    1124           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1125           0 :                 return false;
    1126             :         }
    1127             : 
    1128           0 :         ok = tevent_req_poll(subreq, ev);
    1129           0 :         if (!ok) {
    1130           0 :                 printf("tevent_req_poll() returned false\n");
    1131           0 :                 return false;
    1132             :         }
    1133             : 
    1134           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1135             :                                             &recv_iov, &out_blob);
    1136           0 :         if (!NT_STATUS_IS_OK(status)) {
    1137           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1138             :                         nt_errstr(status));
    1139           0 :                 return false;
    1140             :         }
    1141             : 
    1142           0 :         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
    1143             :                                     &channel_session_key);
    1144           0 :         if (!NT_STATUS_IS_OK(status)) {
    1145           0 :                 printf("gensec_session_key returned %s\n",
    1146             :                         nt_errstr(status));
    1147           0 :                 return false;
    1148             :         }
    1149             : 
    1150           0 :         status = smb2cli_session_set_channel_key(cli2->smb2.session,
    1151             :                                                  channel_session_key,
    1152             :                                                  recv_iov);
    1153           0 :         if (!NT_STATUS_IS_OK(status)) {
    1154           0 :                 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
    1155           0 :                 return false;
    1156             :         }
    1157             : 
    1158           0 :         status = smb2cli_session_create_channel(cli3,
    1159           0 :                                                 cli1->smb2.session,
    1160           0 :                                                 cli3->conn,
    1161           0 :                                                 &cli3->smb2.session);
    1162           0 :         if (!NT_STATUS_IS_OK(status)) {
    1163           0 :                 printf("smb2cli_session_create_channel returned %s\n",
    1164             :                         nt_errstr(status));
    1165           0 :                 return false;
    1166             :         }
    1167             : 
    1168           0 :         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
    1169           0 :         if (!NT_STATUS_IS_OK(status)) {
    1170           0 :                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
    1171           0 :                 return false;
    1172             :         }
    1173             : 
    1174           0 :         gensec_want_feature(auth_generic_state->gensec_security,
    1175             :                             GENSEC_FEATURE_SESSION_KEY);
    1176             : 
    1177           0 :         status = auth_generic_set_creds(auth_generic_state, torture_creds);
    1178           0 :         if (!NT_STATUS_IS_OK(status)) {
    1179           0 :                 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
    1180           0 :                 return false;
    1181             :         }
    1182             : 
    1183           0 :         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
    1184           0 :         if (!NT_STATUS_IS_OK(status)) {
    1185           0 :                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
    1186           0 :                 return false;
    1187             :         }
    1188             : 
    1189           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1190             :                                talloc_tos(), data_blob_null, &in_blob);
    1191           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1192           0 :                 printf("gensec_update returned %s\n", nt_errstr(status));
    1193           0 :                 return false;
    1194             :         }
    1195             : 
    1196           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1197           0 :                                             cli3->conn,
    1198           0 :                                             cli3->timeout,
    1199           0 :                                             cli3->smb2.session,
    1200             :                                             0x01, /* in_flags */
    1201             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1202             :                                             0, /* in_channel */
    1203             :                                             0, /* in_previous_session_id */
    1204             :                                             &in_blob); /* in_security_buffer */
    1205           0 :         if (subreq == NULL) {
    1206           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1207           0 :                 return false;
    1208             :         }
    1209             : 
    1210           0 :         ok = tevent_req_poll(subreq, ev);
    1211           0 :         if (!ok) {
    1212           0 :                 printf("tevent_req_poll() returned false\n");
    1213           0 :                 return false;
    1214             :         }
    1215             : 
    1216           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1217             :                                             NULL, &out_blob);
    1218           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1219           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1220             :                         nt_errstr(status));
    1221           0 :                 return false;
    1222             :         }
    1223             : 
    1224           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1225             :                                talloc_tos(), out_blob, &in_blob);
    1226           0 :         if (!NT_STATUS_IS_OK(status)) {
    1227           0 :                 printf("auth_generic_update returned %s\n", nt_errstr(status));
    1228           0 :                 return false;
    1229             :         }
    1230             : 
    1231           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1232           0 :                                             cli3->conn,
    1233           0 :                                             cli3->timeout,
    1234           0 :                                             cli3->smb2.session,
    1235             :                                             0x01, /* in_flags */
    1236             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1237             :                                             0, /* in_channel */
    1238             :                                             0, /* in_previous_session_id */
    1239             :                                             &in_blob); /* in_security_buffer */
    1240           0 :         if (subreq == NULL) {
    1241           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1242           0 :                 return false;
    1243             :         }
    1244             : 
    1245           0 :         ok = tevent_req_poll(subreq, ev);
    1246           0 :         if (!ok) {
    1247           0 :                 printf("tevent_req_poll() returned false\n");
    1248           0 :                 return false;
    1249             :         }
    1250             : 
    1251           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1252             :                                             &recv_iov, &out_blob);
    1253           0 :         if (!NT_STATUS_IS_OK(status)) {
    1254           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1255             :                         nt_errstr(status));
    1256           0 :                 return false;
    1257             :         }
    1258             : 
    1259           0 :         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
    1260             :                                     &channel_session_key);
    1261           0 :         if (!NT_STATUS_IS_OK(status)) {
    1262           0 :                 printf("gensec_session_key returned %s\n",
    1263             :                         nt_errstr(status));
    1264           0 :                 return false;
    1265             :         }
    1266             : 
    1267           0 :         status = smb2cli_session_set_channel_key(cli3->smb2.session,
    1268             :                                                  channel_session_key,
    1269             :                                                  recv_iov);
    1270           0 :         if (!NT_STATUS_IS_OK(status)) {
    1271           0 :                 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
    1272           0 :                 return false;
    1273             :         }
    1274             : 
    1275           0 :         status = smb2cli_create(
    1276           0 :                 cli2->conn,
    1277           0 :                 cli2->timeout,
    1278           0 :                 cli2->smb2.session,
    1279           0 :                 cli1->smb2.tcon,
    1280             :                 "multi-channel.txt",
    1281             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1282             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1283             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    1284             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    1285             :                 FILE_SHARE_READ|
    1286             :                 FILE_SHARE_WRITE|
    1287             :                 FILE_SHARE_DELETE, /* share_access, */
    1288             :                 FILE_CREATE, /* create_disposition, */
    1289             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1290             :                 NULL, /* smb2_create_blobs *blobs */
    1291             :                 &fid_persistent,
    1292             :                 &fid_volatile,
    1293             :                 NULL,
    1294             :                 NULL,
    1295             :                 NULL,
    1296             :                 NULL);
    1297           0 :         if (!NT_STATUS_IS_OK(status)) {
    1298           0 :                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
    1299           0 :                 return false;
    1300             :         }
    1301             : 
    1302           0 :         status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
    1303           0 :                                cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
    1304             :                                fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
    1305           0 :         if (!NT_STATUS_IS_OK(status)) {
    1306           0 :                 printf("smb2cli_write returned %s\n", nt_errstr(status));
    1307           0 :                 return false;
    1308             :         }
    1309             : 
    1310           0 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
    1311           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1312           0 :         if (!NT_STATUS_IS_OK(status)) {
    1313           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1314           0 :                 return false;
    1315             :         }
    1316             : 
    1317           0 :         status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
    1318           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1319           0 :         if (!NT_STATUS_IS_OK(status)) {
    1320           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1321           0 :                 return false;
    1322             :         }
    1323             : 
    1324           0 :         status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
    1325           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1326           0 :         if (!NT_STATUS_IS_OK(status)) {
    1327           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1328           0 :                 return false;
    1329             :         }
    1330             : 
    1331           0 :         status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
    1332           0 :                               cli1->smb2.tcon, 0x10000, 0, fid_persistent,
    1333             :                               fid_volatile, 2, 0,
    1334             :                               talloc_tos(), &result, &nread);
    1335           0 :         if (!NT_STATUS_IS_OK(status)) {
    1336           0 :                 printf("smb2cli_read returned %s\n", nt_errstr(status));
    1337           0 :                 return false;
    1338             :         }
    1339             : 
    1340           0 :         if (nread != strlen(hello)) {
    1341           0 :                 printf("smb2cli_read returned %d bytes, expected %d\n",
    1342           0 :                        (int)nread, (int)strlen(hello));
    1343           0 :                 return false;
    1344             :         }
    1345             : 
    1346           0 :         if (memcmp(hello, result, nread) != 0) {
    1347           0 :                 printf("smb2cli_read returned '%s', expected '%s'\n",
    1348             :                        result, hello);
    1349           0 :                 return false;
    1350             :         }
    1351             : 
    1352           0 :         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
    1353           0 :         if (!NT_STATUS_IS_OK(status)) {
    1354           0 :                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
    1355           0 :                 return false;
    1356             :         }
    1357             : 
    1358           0 :         gensec_want_feature(auth_generic_state->gensec_security,
    1359             :                             GENSEC_FEATURE_SESSION_KEY);
    1360             : 
    1361           0 :         status = auth_generic_set_creds(auth_generic_state, torture_creds);
    1362           0 :         if (!NT_STATUS_IS_OK(status)) {
    1363           0 :                 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
    1364           0 :                 return false;
    1365             :         }
    1366             : 
    1367           0 :         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
    1368           0 :         if (!NT_STATUS_IS_OK(status)) {
    1369           0 :                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
    1370           0 :                 return false;
    1371             :         }
    1372             : 
    1373           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1374             :                                talloc_tos(), data_blob_null, &in_blob);
    1375           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1376           0 :                 printf("gensec_update returned %s\n", nt_errstr(status));
    1377           0 :                 return false;
    1378             :         }
    1379             : 
    1380           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1381           0 :                                             cli3->conn,
    1382           0 :                                             cli3->timeout,
    1383           0 :                                             cli3->smb2.session,
    1384             :                                             0x0, /* in_flags */
    1385             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1386             :                                             0, /* in_channel */
    1387             :                                             0, /* in_previous_session_id */
    1388             :                                             &in_blob); /* in_security_buffer */
    1389           0 :         if (subreq == NULL) {
    1390           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1391           0 :                 return false;
    1392             :         }
    1393             : 
    1394           0 :         ok = tevent_req_poll(subreq, ev);
    1395           0 :         if (!ok) {
    1396           0 :                 printf("tevent_req_poll() returned false\n");
    1397           0 :                 return false;
    1398             :         }
    1399             : 
    1400           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1401             :                                             NULL, &out_blob);
    1402           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1403           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1404             :                         nt_errstr(status));
    1405           0 :                 return false;
    1406             :         }
    1407             : 
    1408           0 :         status = gensec_update(auth_generic_state->gensec_security,
    1409             :                                talloc_tos(), out_blob, &in_blob);
    1410           0 :         if (!NT_STATUS_IS_OK(status)) {
    1411           0 :                 printf("auth_generic_update returned %s\n", nt_errstr(status));
    1412           0 :                 return false;
    1413             :         }
    1414             : 
    1415           0 :         status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
    1416           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1417           0 :         if (!NT_STATUS_IS_OK(status)) {
    1418           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1419           0 :                 return false;
    1420             :         }
    1421             : 
    1422           0 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
    1423           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1424           0 :         if (!NT_STATUS_IS_OK(status)) {
    1425           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1426           0 :                 return false;
    1427             :         }
    1428             : 
    1429           0 :         status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
    1430           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1431           0 :         if (!NT_STATUS_IS_OK(status)) {
    1432           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1433           0 :                 return false;
    1434             :         }
    1435             : 
    1436           0 :         status = smb2cli_create(
    1437           0 :                 cli1->conn,
    1438           0 :                 cli1->timeout,
    1439           0 :                 cli1->smb2.session,
    1440           0 :                 cli1->smb2.tcon,
    1441             :                 "multi-channel-invalid.txt",
    1442             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1443             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1444             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    1445             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    1446             :                 FILE_SHARE_READ|
    1447             :                 FILE_SHARE_WRITE|
    1448             :                 FILE_SHARE_DELETE, /* share_access, */
    1449             :                 FILE_CREATE, /* create_disposition, */
    1450             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1451             :                 NULL, /* smb2_create_blobs *blobs */
    1452             :                 &fid_persistent,
    1453             :                 &fid_volatile,
    1454             :                 NULL,
    1455             :                 NULL,
    1456             :                 NULL,
    1457             :                 NULL);
    1458           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1459           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    1460           0 :                 return false;
    1461             :         }
    1462             : 
    1463           0 :         status = smb2cli_create(
    1464           0 :                 cli2->conn,
    1465           0 :                 cli2->timeout,
    1466           0 :                 cli2->smb2.session,
    1467           0 :                 cli1->smb2.tcon,
    1468             :                 "multi-channel-invalid.txt",
    1469             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1470             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1471             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    1472             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    1473             :                 FILE_SHARE_READ|
    1474             :                 FILE_SHARE_WRITE|
    1475             :                 FILE_SHARE_DELETE, /* share_access, */
    1476             :                 FILE_CREATE, /* create_disposition, */
    1477             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1478             :                 NULL, /* smb2_create_blobs *blobs */
    1479             :                 &fid_persistent,
    1480             :                 &fid_volatile,
    1481             :                 NULL,
    1482             :                 NULL,
    1483             :                 NULL,
    1484             :                 NULL);
    1485           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1486           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    1487           0 :                 return false;
    1488             :         }
    1489             : 
    1490           0 :         status = smb2cli_create(
    1491           0 :                 cli3->conn,
    1492           0 :                 cli3->timeout,
    1493           0 :                 cli3->smb2.session,
    1494           0 :                 cli1->smb2.tcon,
    1495             :                 "multi-channel-invalid.txt",
    1496             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1497             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1498             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    1499             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    1500             :                 FILE_SHARE_READ|
    1501             :                 FILE_SHARE_WRITE|
    1502             :                 FILE_SHARE_DELETE, /* share_access, */
    1503             :                 FILE_CREATE, /* create_disposition, */
    1504             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1505             :                 NULL, /* smb2_create_blobs *blobs */
    1506             :                 &fid_persistent,
    1507             :                 &fid_volatile,
    1508             :                 NULL,
    1509             :                 NULL,
    1510             :                 NULL,
    1511             :                 NULL);
    1512           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1513           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    1514           0 :                 return false;
    1515             :         }
    1516             : 
    1517           0 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1518           0 :                                             cli2->conn,
    1519           0 :                                             cli2->timeout,
    1520           0 :                                             cli2->smb2.session,
    1521             :                                             0x0, /* in_flags */
    1522             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1523             :                                             0, /* in_channel */
    1524             :                                             0, /* in_previous_session_id */
    1525             :                                             &in_blob); /* in_security_buffer */
    1526           0 :         if (subreq == NULL) {
    1527           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1528           0 :                 return false;
    1529             :         }
    1530             : 
    1531           0 :         ok = tevent_req_poll(subreq, ev);
    1532           0 :         if (!ok) {
    1533           0 :                 printf("tevent_req_poll() returned false\n");
    1534           0 :                 return false;
    1535             :         }
    1536             : 
    1537           0 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1538             :                                             &recv_iov, &out_blob);
    1539           0 :         if (!NT_STATUS_IS_OK(status)) {
    1540           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1541             :                         nt_errstr(status));
    1542           0 :                 return false;
    1543             :         }
    1544             : 
    1545           0 :         status = smb2cli_close(cli3->conn, cli3->timeout, cli3->smb2.session,
    1546           0 :                                cli1->smb2.tcon, 0, fid_persistent, fid_volatile);
    1547           0 :         if (!NT_STATUS_IS_OK(status)) {
    1548           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    1549           0 :                 return false;
    1550             :         }
    1551             : 
    1552           0 :         status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
    1553           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1554           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
    1555           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1556           0 :                 return false;
    1557             :         }
    1558             : 
    1559           0 :         status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
    1560           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1561           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
    1562           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1563           0 :                 return false;
    1564             :         }
    1565             : 
    1566           0 :         status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
    1567           0 :                                cli1->smb2.tcon, fid_persistent, fid_volatile);
    1568           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
    1569           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1570           0 :                 return false;
    1571             :         }
    1572             : 
    1573           0 :         return true;
    1574             : }
    1575             : 
    1576           4 : bool run_smb2_session_reauth(int dummy)
    1577             : {
    1578           0 :         struct cli_state *cli;
    1579           0 :         NTSTATUS status;
    1580           0 :         bool ok;
    1581           0 :         uint64_t fid_persistent, fid_volatile;
    1582           0 :         uint64_t dir_persistent, dir_volatile;
    1583           0 :         uint8_t *dir_data;
    1584           0 :         uint32_t dir_data_length;
    1585           0 :         struct tevent_context *ev;
    1586           0 :         struct tevent_req *subreq;
    1587           4 :         DATA_BLOB in_blob = data_blob_null;
    1588           0 :         DATA_BLOB out_blob;
    1589           0 :         DATA_BLOB in_input_buffer;
    1590           0 :         DATA_BLOB out_output_buffer;
    1591           0 :         uint8_t in_file_info_class;
    1592           0 :         struct auth_generic_state *auth_generic_state;
    1593           0 :         struct iovec *recv_iov;
    1594           0 :         uint32_t saved_tid;
    1595           0 :         struct smbXcli_tcon *saved_tcon;
    1596             : 
    1597           4 :         printf("Starting SMB2-SESSION_REAUTH\n");
    1598             : 
    1599           4 :         if (!torture_init_connection(&cli)) {
    1600           0 :                 return false;
    1601             :         }
    1602             : 
    1603             :         /*
    1604             :          * PROTOCOL_SMB2_22 has a bug in win8pre0
    1605             :          * it behaves like PROTOCOL_SMB2_02
    1606             :          * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
    1607             :          * while it allows it on PROTOCOL_SMB2_10.
    1608             :          */
    1609           4 :         status = smbXcli_negprot(cli->conn,
    1610           4 :                                  cli->timeout,
    1611             :                                  PROTOCOL_SMB2_10,
    1612             :                                  PROTOCOL_SMB2_10,
    1613             :                                  NULL,
    1614             :                                  NULL,
    1615             :                                  NULL);
    1616           4 :         if (!NT_STATUS_IS_OK(status)) {
    1617           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    1618           0 :                 return false;
    1619             :         }
    1620             : 
    1621           4 :         status = cli_session_setup_creds(cli, torture_creds);
    1622           4 :         if (!NT_STATUS_IS_OK(status)) {
    1623           0 :                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
    1624           0 :                 return false;
    1625             :         }
    1626             : 
    1627           4 :         status = cli_tree_connect(cli, share, "?????", NULL);
    1628           4 :         if (!NT_STATUS_IS_OK(status)) {
    1629           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    1630           0 :                 return false;
    1631             :         }
    1632             : 
    1633           4 :         status = smb2cli_create(
    1634           4 :                 cli->conn,
    1635           4 :                 cli->timeout,
    1636           4 :                 cli->smb2.session,
    1637           4 :                 cli->smb2.tcon,
    1638             :                 "session-reauth.txt",
    1639             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1640             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1641             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    1642             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    1643             :                 FILE_SHARE_READ|
    1644             :                 FILE_SHARE_WRITE|
    1645             :                 FILE_SHARE_DELETE, /* share_access, */
    1646             :                 FILE_CREATE, /* create_disposition, */
    1647             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1648             :                 NULL, /* smb2_create_blobs *blobs */
    1649             :                 &fid_persistent,
    1650             :                 &fid_volatile,
    1651             :                 NULL,
    1652             :                 NULL,
    1653             :                 NULL,
    1654             :                 NULL);
    1655           4 :         if (!NT_STATUS_IS_OK(status)) {
    1656           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    1657           0 :                 return false;
    1658             :         }
    1659             : 
    1660           4 :         status = smb2cli_create(
    1661           4 :                 cli->conn,
    1662           4 :                 cli->timeout,
    1663           4 :                 cli->smb2.session,
    1664           4 :                 cli->smb2.tcon,
    1665             :                 "",
    1666             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1667             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1668             :                 SEC_STD_SYNCHRONIZE|
    1669             :                 SEC_DIR_LIST|
    1670             :                 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
    1671             :                 0, /* file_attributes, */
    1672             :                 FILE_SHARE_READ|
    1673             :                 FILE_SHARE_WRITE|
    1674             :                 FILE_SHARE_DELETE, /* share_access, */
    1675             :                 FILE_OPEN, /* create_disposition, */
    1676             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    1677             :                 FILE_DIRECTORY_FILE, /* create_options, */
    1678             :                 NULL, /* smb2_create_blobs *blobs */
    1679             :                 &dir_persistent,
    1680             :                 &dir_volatile,
    1681             :                 NULL,
    1682             :                 NULL,
    1683             :                 NULL,
    1684             :                 NULL);
    1685           4 :         if (!NT_STATUS_IS_OK(status)) {
    1686           0 :                 printf("smb2cli_create returned %s\n", nt_errstr(status));
    1687           0 :                 return false;
    1688             :         }
    1689             : 
    1690           4 :         status = smb2cli_query_directory(
    1691           4 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    1692             :                 1, 0x3, 0, dir_persistent, dir_volatile,
    1693             :                 "session-reauth.txt", 0xffff,
    1694             :                 talloc_tos(), &dir_data, &dir_data_length);
    1695           4 :         if (!NT_STATUS_IS_OK(status)) {
    1696           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    1697           0 :                 return false;
    1698             :         }
    1699             : 
    1700           4 :         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
    1701           4 :         if (!NT_STATUS_IS_OK(status)) {
    1702           0 :                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
    1703           0 :                 return false;
    1704             :         }
    1705             : 
    1706           4 :         gensec_want_feature(auth_generic_state->gensec_security,
    1707             :                             GENSEC_FEATURE_SESSION_KEY);
    1708             : 
    1709           4 :         status = auth_generic_set_creds(auth_generic_state, torture_creds);
    1710           4 :         if (!NT_STATUS_IS_OK(status)) {
    1711           0 :                 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
    1712           0 :                 return false;
    1713             :         }
    1714             : 
    1715           4 :         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
    1716           4 :         if (!NT_STATUS_IS_OK(status)) {
    1717           0 :                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
    1718           0 :                 return false;
    1719             :         }
    1720             : 
    1721           4 :         ev = samba_tevent_context_init(talloc_tos());
    1722           4 :         if (ev == NULL) {
    1723           0 :                 printf("samba_tevent_context_init() returned NULL\n");
    1724           0 :                 return false;
    1725             :         }
    1726             : 
    1727           4 :         status = gensec_update(auth_generic_state->gensec_security,
    1728             :                                talloc_tos(), data_blob_null, &in_blob);
    1729           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1730           0 :                 printf("gensec_update returned %s\n", nt_errstr(status));
    1731           0 :                 return false;
    1732             :         }
    1733             : 
    1734           4 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1735           4 :                                             cli->conn,
    1736           4 :                                             cli->timeout,
    1737           4 :                                             cli->smb2.session,
    1738             :                                             0x0, /* in_flags */
    1739             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1740             :                                             0, /* in_channel */
    1741             :                                             0, /* in_previous_session_id */
    1742             :                                             &in_blob); /* in_security_buffer */
    1743           4 :         if (subreq == NULL) {
    1744           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1745           0 :                 return false;
    1746             :         }
    1747             : 
    1748           4 :         ok = tevent_req_poll(subreq, ev);
    1749           4 :         if (!ok) {
    1750           0 :                 printf("tevent_req_poll() returned false\n");
    1751           0 :                 return false;
    1752             :         }
    1753             : 
    1754           4 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1755             :                                             NULL, &out_blob);
    1756           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1757           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1758             :                         nt_errstr(status));
    1759           0 :                 return false;
    1760             :         }
    1761             : 
    1762           4 :         status = gensec_update(auth_generic_state->gensec_security,
    1763             :                                talloc_tos(), out_blob, &in_blob);
    1764           4 :         if (!NT_STATUS_IS_OK(status)) {
    1765           0 :                 printf("auth_generic_update returned %s\n", nt_errstr(status));
    1766           0 :                 return false;
    1767             :         }
    1768             : 
    1769           4 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    1770           4 :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    1771           4 :         if (!NT_STATUS_IS_OK(status)) {
    1772           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1773           0 :                 return false;
    1774             :         }
    1775             : 
    1776           4 :         status = smb2cli_query_directory(
    1777           4 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    1778             :                 1, 0x3, 0, dir_persistent, dir_volatile,
    1779             :                 "session-reauth.txt", 0xffff,
    1780             :                 talloc_tos(), &dir_data, &dir_data_length);
    1781           4 :         if (!NT_STATUS_IS_OK(status)) {
    1782           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    1783           0 :                 return false;
    1784             :         }
    1785             : 
    1786             :         /*
    1787             :          * query_info seems to be a path based operation on Windows...
    1788             :          */
    1789           4 :         status = smb2cli_query_info(cli->conn,
    1790           4 :                                     cli->timeout,
    1791           4 :                                     cli->smb2.session,
    1792           4 :                                     cli->smb2.tcon,
    1793             :                                     SMB2_0_INFO_SECURITY,
    1794             :                                     0, /* in_file_info_class */
    1795             :                                     1024, /* in_max_output_length */
    1796             :                                     NULL, /* in_input_buffer */
    1797             :                                     SECINFO_OWNER, /* in_additional_info */
    1798             :                                     0, /* in_flags */
    1799             :                                     fid_persistent,
    1800             :                                     fid_volatile,
    1801             :                                     talloc_tos(),
    1802             :                                     &out_output_buffer);
    1803           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1804           0 :                 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
    1805           0 :                 return false;
    1806             :         }
    1807             : 
    1808           4 :         in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
    1809           4 :         status = smb2cli_query_info(cli->conn,
    1810           4 :                                     cli->timeout,
    1811           4 :                                     cli->smb2.session,
    1812           4 :                                     cli->smb2.tcon,
    1813             :                                     SMB2_0_INFO_FILE,
    1814             :                                     in_file_info_class,
    1815             :                                     1024, /* in_max_output_length */
    1816             :                                     NULL, /* in_input_buffer */
    1817             :                                     0, /* in_additional_info */
    1818             :                                     0, /* in_flags */
    1819             :                                     fid_persistent,
    1820             :                                     fid_volatile,
    1821             :                                     talloc_tos(),
    1822             :                                     &out_output_buffer);
    1823           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1824           0 :                 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
    1825           0 :                 return false;
    1826             :         }
    1827             : 
    1828           4 :         in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
    1829           4 :         SBVAL(in_input_buffer.data, 0, 512);
    1830             : 
    1831           4 :         in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
    1832           4 :         status = smb2cli_set_info(cli->conn,
    1833           4 :                                   cli->timeout,
    1834           4 :                                   cli->smb2.session,
    1835           4 :                                   cli->smb2.tcon,
    1836             :                                   SMB2_0_INFO_FILE,
    1837             :                                   in_file_info_class,
    1838             :                                   &in_input_buffer,
    1839             :                                   0, /* in_additional_info */
    1840             :                                   fid_persistent,
    1841             :                                   fid_volatile);
    1842           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1843           0 :                 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
    1844           0 :                 return false;
    1845             :         }
    1846             : 
    1847           4 :         status = smb2cli_create(
    1848           4 :                 cli->conn,
    1849           4 :                 cli->timeout,
    1850           4 :                 cli->smb2.session,
    1851           4 :                 cli->smb2.tcon,
    1852             :                 "session-reauth-invalid.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|
    1858             :                 FILE_SHARE_WRITE|
    1859             :                 FILE_SHARE_DELETE, /* share_access, */
    1860             :                 FILE_CREATE, /* create_disposition, */
    1861             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    1862             :                 NULL, /* smb2_create_blobs *blobs */
    1863             :                 &fid_persistent,
    1864             :                 &fid_volatile,
    1865             :                 NULL,
    1866             :                 NULL,
    1867             :                 NULL,
    1868             :                 NULL);
    1869           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1870           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    1871           0 :                 return false;
    1872             :         }
    1873             : 
    1874           4 :         status = smb2cli_create(
    1875           4 :                 cli->conn,
    1876           4 :                 cli->timeout,
    1877           4 :                 cli->smb2.session,
    1878           4 :                 cli->smb2.tcon,
    1879             :                 "",
    1880             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    1881             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    1882             :                 SEC_STD_SYNCHRONIZE|
    1883             :                 SEC_DIR_LIST|
    1884             :                 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
    1885             :                 0, /* file_attributes, */
    1886             :                 FILE_SHARE_READ|
    1887             :                 FILE_SHARE_WRITE|
    1888             :                 FILE_SHARE_DELETE, /* share_access, */
    1889             :                 FILE_OPEN, /* create_disposition, */
    1890             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    1891             :                 FILE_DIRECTORY_FILE, /* create_options, */
    1892             :                 NULL, /* smb2_create_blobs *blobs */
    1893             :                 &dir_persistent,
    1894             :                 &dir_volatile,
    1895             :                 NULL,
    1896             :                 NULL,
    1897             :                 NULL,
    1898             :                 NULL);
    1899           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1900           0 :                 printf("smb2cli_create returned %s\n", nt_errstr(status));
    1901           0 :                 return false;
    1902             :         }
    1903             : 
    1904           4 :         saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
    1905           4 :         saved_tcon = cli->smb2.tcon;
    1906           4 :         cli->smb2.tcon = smbXcli_tcon_create(cli);
    1907           4 :         smb2cli_tcon_set_values(cli->smb2.tcon,
    1908             :                                 NULL, /* session */
    1909             :                                 saved_tid,
    1910             :                                 0, /* type */
    1911             :                                 0, /* flags */
    1912             :                                 0, /* capabilities */
    1913             :                                 0  /* maximal_access */);
    1914           4 :         status = cli_tree_connect(cli, share, "?????", NULL);
    1915           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    1916           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    1917           0 :                 return false;
    1918             :         }
    1919           4 :         talloc_free(cli->smb2.tcon);
    1920           4 :         cli->smb2.tcon = saved_tcon;
    1921             : 
    1922           4 :         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
    1923           4 :                                             cli->conn,
    1924           4 :                                             cli->timeout,
    1925           4 :                                             cli->smb2.session,
    1926             :                                             0x0, /* in_flags */
    1927             :                                             SMB2_CAP_DFS, /* in_capabilities */
    1928             :                                             0, /* in_channel */
    1929             :                                             0, /* in_previous_session_id */
    1930             :                                             &in_blob); /* in_security_buffer */
    1931           4 :         if (subreq == NULL) {
    1932           0 :                 printf("smb2cli_session_setup_send() returned NULL\n");
    1933           0 :                 return false;
    1934             :         }
    1935             : 
    1936           4 :         ok = tevent_req_poll(subreq, ev);
    1937           4 :         if (!ok) {
    1938           0 :                 printf("tevent_req_poll() returned false\n");
    1939           0 :                 return false;
    1940             :         }
    1941             : 
    1942           4 :         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
    1943             :                                             &recv_iov, &out_blob);
    1944           4 :         if (!NT_STATUS_IS_OK(status)) {
    1945           0 :                 printf("smb2cli_session_setup_recv returned %s\n",
    1946             :                         nt_errstr(status));
    1947           0 :                 return false;
    1948             :         }
    1949             : 
    1950           4 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    1951           4 :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    1952           4 :         if (!NT_STATUS_IS_OK(status)) {
    1953           0 :                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
    1954           0 :                 return false;
    1955             :         }
    1956             : 
    1957           4 :         status = smb2cli_query_info(cli->conn,
    1958           4 :                                     cli->timeout,
    1959           4 :                                     cli->smb2.session,
    1960           4 :                                     cli->smb2.tcon,
    1961             :                                     SMB2_0_INFO_SECURITY,
    1962             :                                     0, /* in_file_info_class */
    1963             :                                     1024, /* in_max_output_length */
    1964             :                                     NULL, /* in_input_buffer */
    1965             :                                     SECINFO_OWNER, /* in_additional_info */
    1966             :                                     0, /* in_flags */
    1967             :                                     fid_persistent,
    1968             :                                     fid_volatile,
    1969             :                                     talloc_tos(),
    1970             :                                     &out_output_buffer);
    1971           4 :         if (!NT_STATUS_IS_OK(status)) {
    1972           0 :                 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
    1973           0 :                 return false;
    1974             :         }
    1975             : 
    1976           4 :         in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
    1977           4 :         status = smb2cli_query_info(cli->conn,
    1978           4 :                                     cli->timeout,
    1979           4 :                                     cli->smb2.session,
    1980           4 :                                     cli->smb2.tcon,
    1981             :                                     SMB2_0_INFO_FILE,
    1982             :                                     in_file_info_class,
    1983             :                                     1024, /* in_max_output_length */
    1984             :                                     NULL, /* in_input_buffer */
    1985             :                                     0, /* in_additional_info */
    1986             :                                     0, /* in_flags */
    1987             :                                     fid_persistent,
    1988             :                                     fid_volatile,
    1989             :                                     talloc_tos(),
    1990             :                                     &out_output_buffer);
    1991           4 :         if (!NT_STATUS_IS_OK(status)) {
    1992           0 :                 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
    1993           0 :                 return false;
    1994             :         }
    1995             : 
    1996           4 :         in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
    1997           4 :         SBVAL(in_input_buffer.data, 0, 512);
    1998             : 
    1999           4 :         in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
    2000           4 :         status = smb2cli_set_info(cli->conn,
    2001           4 :                                   cli->timeout,
    2002           4 :                                   cli->smb2.session,
    2003           4 :                                   cli->smb2.tcon,
    2004             :                                   SMB2_0_INFO_FILE,
    2005             :                                   in_file_info_class,
    2006             :                                   &in_input_buffer,
    2007             :                                   0, /* in_additional_info */
    2008             :                                   fid_persistent,
    2009             :                                   fid_volatile);
    2010           4 :         if (!NT_STATUS_IS_OK(status)) {
    2011           0 :                 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
    2012           0 :                 return false;
    2013             :         }
    2014             : 
    2015           4 :         in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
    2016           4 :         status = smb2cli_query_info(cli->conn,
    2017           4 :                                     cli->timeout,
    2018           4 :                                     cli->smb2.session,
    2019           4 :                                     cli->smb2.tcon,
    2020             :                                     SMB2_0_INFO_FILE,
    2021             :                                     in_file_info_class,
    2022             :                                     1024, /* in_max_output_length */
    2023             :                                     NULL, /* in_input_buffer */
    2024             :                                     0, /* in_additional_info */
    2025             :                                     0, /* in_flags */
    2026             :                                     fid_persistent,
    2027             :                                     fid_volatile,
    2028             :                                     talloc_tos(),
    2029             :                                     &out_output_buffer);
    2030           4 :         if (!NT_STATUS_IS_OK(status)) {
    2031           0 :                 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
    2032           0 :                 return false;
    2033             :         }
    2034             : 
    2035           4 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2036           4 :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2037           4 :         if (!NT_STATUS_IS_OK(status)) {
    2038           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2039           0 :                 return false;
    2040             :         }
    2041             : 
    2042           4 :         status = smb2cli_create(
    2043           4 :                 cli->conn,
    2044           4 :                 cli->timeout,
    2045           4 :                 cli->smb2.session,
    2046           4 :                 cli->smb2.tcon,
    2047             :                 "session-reauth.txt",
    2048             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2049             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2050             :                 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
    2051             :                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    2052             :                 FILE_SHARE_READ|
    2053             :                 FILE_SHARE_WRITE|
    2054             :                 FILE_SHARE_DELETE, /* share_access, */
    2055             :                 FILE_CREATE, /* create_disposition, */
    2056             :                 FILE_DELETE_ON_CLOSE, /* create_options, */
    2057             :                 NULL, /* smb2_create_blobs *blobs */
    2058             :                 &fid_persistent,
    2059             :                 &fid_volatile,
    2060             :                 NULL,
    2061             :                 NULL,
    2062             :                 NULL,
    2063             :                 NULL);
    2064           4 :         if (!NT_STATUS_IS_OK(status)) {
    2065           0 :                 printf("smb2cli_create %s\n", nt_errstr(status));
    2066           0 :                 return false;
    2067             :         }
    2068             : 
    2069           4 :         status = smb2cli_query_directory(
    2070           4 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    2071             :                 1, 0x3, 0, dir_persistent, dir_volatile,
    2072             :                 "session-reauth.txt", 0xffff,
    2073             :                 talloc_tos(), &dir_data, &dir_data_length);
    2074           4 :         if (!NT_STATUS_IS_OK(status)) {
    2075           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    2076           0 :                 return false;
    2077             :         }
    2078             : 
    2079           4 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2080           4 :                                cli->smb2.tcon, 0, dir_persistent, dir_volatile);
    2081           4 :         if (!NT_STATUS_IS_OK(status)) {
    2082           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2083           0 :                 return false;
    2084             :         }
    2085             : 
    2086           4 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2087           4 :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2088           4 :         if (!NT_STATUS_IS_OK(status)) {
    2089           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2090           0 :                 return false;
    2091             :         }
    2092             : 
    2093           4 :         saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
    2094           4 :         saved_tcon = cli->smb2.tcon;
    2095           4 :         cli->smb2.tcon = smbXcli_tcon_create(cli);
    2096           4 :         smb2cli_tcon_set_values(cli->smb2.tcon,
    2097             :                                 NULL, /* session */
    2098             :                                 saved_tid,
    2099             :                                 0, /* type */
    2100             :                                 0, /* flags */
    2101             :                                 0, /* capabilities */
    2102             :                                 0  /* maximal_access */);
    2103           4 :         status = cli_tree_connect(cli, share, "?????", NULL);
    2104           4 :         if (!NT_STATUS_IS_OK(status)) {
    2105           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    2106           0 :                 return false;
    2107             :         }
    2108           4 :         talloc_free(cli->smb2.tcon);
    2109           4 :         cli->smb2.tcon = saved_tcon;
    2110             : 
    2111           4 :         return true;
    2112             : }
    2113             : 
    2114          55 : static NTSTATUS check_size(struct cli_state *cli,
    2115             :                                 uint16_t fnum,
    2116             :                                 const char *fname,
    2117             :                                 size_t size)
    2118             : {
    2119          55 :         off_t size_read = 0;
    2120             : 
    2121          55 :         NTSTATUS status = cli_qfileinfo_basic(cli,
    2122             :                                 fnum,
    2123             :                                 NULL,
    2124             :                                 &size_read,
    2125             :                                 NULL,
    2126             :                                 NULL,
    2127             :                                 NULL,
    2128             :                                 NULL,
    2129             :                                 NULL);
    2130             : 
    2131          55 :         if (!NT_STATUS_IS_OK(status)) {
    2132           0 :                 printf("cli_qfileinfo_basic of %s failed (%s)\n",
    2133             :                         fname,
    2134             :                         nt_errstr(status));
    2135           0 :                 return status;
    2136             :         }
    2137             : 
    2138          55 :         if (size != size_read) {
    2139           0 :                 printf("size (%u) != size_read(%u) for %s\n",
    2140             :                         (unsigned int)size,
    2141             :                         (unsigned int)size_read,
    2142             :                         fname);
    2143             :                 /* Use EOF to mean bad size. */
    2144           0 :                 return NT_STATUS_END_OF_FILE;
    2145             :         }
    2146          55 :         return NT_STATUS_OK;
    2147             : }
    2148             : 
    2149             : /* Ensure cli_ftruncate() works for SMB2. */
    2150             : 
    2151           5 : bool run_smb2_ftruncate(int dummy)
    2152             : {
    2153           5 :         struct cli_state *cli = NULL;
    2154           5 :         const char *fname = "smb2_ftruncate.txt";
    2155           5 :         uint16_t fnum = (uint16_t)-1;
    2156           5 :         bool correct = false;
    2157           5 :         size_t buflen = 1024*1024;
    2158           5 :         uint8_t *buf = NULL;
    2159           0 :         unsigned int i;
    2160           0 :         NTSTATUS status;
    2161             : 
    2162           5 :         printf("Starting SMB2-FTRUNCATE\n");
    2163             : 
    2164           5 :         if (!torture_init_connection(&cli)) {
    2165           0 :                 goto fail;
    2166             :         }
    2167             : 
    2168           5 :         status = smbXcli_negprot(cli->conn,
    2169           5 :                                  cli->timeout,
    2170             :                                  PROTOCOL_SMB2_02,
    2171             :                                  PROTOCOL_SMB2_02,
    2172             :                                  NULL,
    2173             :                                  NULL,
    2174             :                                  NULL);
    2175           5 :         if (!NT_STATUS_IS_OK(status)) {
    2176           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    2177           0 :                 goto fail;
    2178             :         }
    2179             : 
    2180           5 :         status = cli_session_setup_creds(cli, torture_creds);
    2181           5 :         if (!NT_STATUS_IS_OK(status)) {
    2182           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    2183           0 :                 goto fail;
    2184             :         }
    2185             : 
    2186           5 :         status = cli_tree_connect(cli, share, "?????", NULL);
    2187           5 :         if (!NT_STATUS_IS_OK(status)) {
    2188           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    2189           0 :                 goto fail;
    2190             :         }
    2191             : 
    2192           5 :         cli_setatr(cli, fname, 0, 0);
    2193           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2194             : 
    2195           5 :         status = cli_ntcreate(cli,
    2196             :                                 fname,
    2197             :                                 0,
    2198             :                                 GENERIC_ALL_ACCESS,
    2199             :                                 FILE_ATTRIBUTE_NORMAL,
    2200             :                                 FILE_SHARE_NONE,
    2201             :                                 FILE_CREATE,
    2202             :                                 0,
    2203             :                                 0,
    2204             :                                 &fnum,
    2205             :                                 NULL);
    2206             : 
    2207           5 :         if (!NT_STATUS_IS_OK(status)) {
    2208           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    2209           0 :                 goto fail;
    2210             :         }
    2211             : 
    2212           5 :         buf = talloc_zero_array(cli, uint8_t, buflen);
    2213           5 :         if (buf == NULL) {
    2214           0 :                 goto fail;
    2215             :         }
    2216             : 
    2217             :         /* Write 1MB. */
    2218           5 :         status = cli_writeall(cli,
    2219             :                                 fnum,
    2220             :                                 0,
    2221             :                                 buf,
    2222             :                                 0,
    2223             :                                 buflen,
    2224             :                                 NULL);
    2225             : 
    2226           5 :         if (!NT_STATUS_IS_OK(status)) {
    2227           0 :                 printf("write of %u to %s failed (%s)\n",
    2228             :                         (unsigned int)buflen,
    2229             :                         fname,
    2230             :                         nt_errstr(status));
    2231           0 :                 goto fail;
    2232             :         }
    2233             : 
    2234           5 :         status = check_size(cli, fnum, fname, buflen);
    2235           5 :         if (!NT_STATUS_IS_OK(status)) {
    2236           0 :                 goto fail;
    2237             :         }
    2238             : 
    2239             :         /* Now ftruncate. */
    2240          55 :         for ( i = 0; i < 10; i++) {
    2241          50 :                 status = cli_ftruncate(cli, fnum, i*1024);
    2242          50 :                 if (!NT_STATUS_IS_OK(status)) {
    2243           0 :                         printf("cli_ftruncate %u of %s failed (%s)\n",
    2244             :                                 (unsigned int)i*1024,
    2245             :                                 fname,
    2246             :                                 nt_errstr(status));
    2247           0 :                         goto fail;
    2248             :                 }
    2249          50 :                 status = check_size(cli, fnum, fname, i*1024);
    2250          50 :                 if (!NT_STATUS_IS_OK(status)) {
    2251           0 :                         goto fail;
    2252             :                 }
    2253             :         }
    2254             : 
    2255           5 :         correct = true;
    2256             : 
    2257           5 :   fail:
    2258             : 
    2259           5 :         if (cli == NULL) {
    2260           0 :                 return false;
    2261             :         }
    2262             : 
    2263           5 :         if (fnum != (uint16_t)-1) {
    2264           5 :                 cli_close(cli, fnum);
    2265             :         }
    2266           5 :         cli_setatr(cli, fname, 0, 0);
    2267           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2268             : 
    2269           5 :         if (!torture_close_connection(cli)) {
    2270           0 :                 correct = false;
    2271             :         }
    2272           5 :         return correct;
    2273             : }
    2274             : 
    2275             : /* Ensure SMB2 flush on directories behaves correctly. */
    2276             : 
    2277           9 : static bool test_dir_fsync(struct cli_state *cli, const char *path)
    2278             : {
    2279           0 :         NTSTATUS status;
    2280           0 :         uint64_t fid_persistent, fid_volatile;
    2281           9 :         uint8_t *dir_data = NULL;
    2282           9 :         uint32_t dir_data_length = 0;
    2283             : 
    2284             :         /* Open directory - no write abilities. */
    2285           9 :         status = smb2cli_create(
    2286             :                 cli->conn,
    2287           9 :                 cli->timeout,
    2288             :                 cli->smb2.session,
    2289             :                 cli->smb2.tcon,
    2290             :                 path,
    2291             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2292             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2293             :                 SEC_STD_SYNCHRONIZE|
    2294             :                 SEC_DIR_LIST|
    2295             :                 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
    2296             :                 0, /* file_attributes, */
    2297             :                 FILE_SHARE_READ|
    2298             :                 FILE_SHARE_WRITE|
    2299             :                 FILE_SHARE_DELETE, /* share_access, */
    2300             :                 FILE_OPEN, /* create_disposition, */
    2301             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    2302             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2303             :                 NULL, /* smb2_create_blobs *blobs */
    2304             :                 &fid_persistent,
    2305             :                 &fid_volatile,
    2306             :                 NULL,
    2307             :                 NULL,
    2308             :                 NULL,
    2309             :                 NULL);
    2310           9 :         if (!NT_STATUS_IS_OK(status)) {
    2311           0 :                 printf("smb2cli_create '%s' (readonly) returned %s\n",
    2312             :                         path,
    2313             :                         nt_errstr(status));
    2314           0 :                 return false;
    2315             :         }
    2316             : 
    2317           9 :         status = smb2cli_query_directory(
    2318           9 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    2319             :                 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
    2320             :                 talloc_tos(), &dir_data, &dir_data_length);
    2321             : 
    2322           9 :         if (!NT_STATUS_IS_OK(status)) {
    2323           0 :                 printf("smb2cli_query_directory returned %s\n",
    2324             :                         nt_errstr(status));
    2325           0 :                 return false;
    2326             :         }
    2327             : 
    2328             :         /* Open directory no write access. Flush should fail. */
    2329             : 
    2330           9 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    2331             :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    2332           9 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    2333           1 :                 printf("smb2cli_flush on a read-only directory returned %s\n",
    2334             :                         nt_errstr(status));
    2335           1 :                 return false;
    2336             :         }
    2337             : 
    2338           8 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2339             :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2340           8 :         if (!NT_STATUS_IS_OK(status)) {
    2341           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2342           0 :                 return false;
    2343             :         }
    2344             : 
    2345             :         /* Open directory write-attributes only. Flush should still fail. */
    2346             : 
    2347           8 :         status = smb2cli_create(
    2348             :                 cli->conn,
    2349           8 :                 cli->timeout,
    2350             :                 cli->smb2.session,
    2351             :                 cli->smb2.tcon,
    2352             :                 path,
    2353             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2354             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2355             :                 SEC_STD_SYNCHRONIZE|
    2356             :                 SEC_DIR_LIST|
    2357             :                 SEC_DIR_WRITE_ATTRIBUTE|
    2358             :                 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
    2359             :                 0, /* file_attributes, */
    2360             :                 FILE_SHARE_READ|
    2361             :                 FILE_SHARE_WRITE|
    2362             :                 FILE_SHARE_DELETE, /* share_access, */
    2363             :                 FILE_OPEN, /* create_disposition, */
    2364             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    2365             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2366             :                 NULL, /* smb2_create_blobs *blobs */
    2367             :                 &fid_persistent,
    2368             :                 &fid_volatile,
    2369             :                 NULL,
    2370             :                 NULL,
    2371             :                 NULL,
    2372             :                 NULL);
    2373           8 :         if (!NT_STATUS_IS_OK(status)) {
    2374           0 :                 printf("smb2cli_create '%s' (write attr) returned %s\n",
    2375             :                         path,
    2376             :                         nt_errstr(status));
    2377           0 :                 return false;
    2378             :         }
    2379             : 
    2380           8 :         status = smb2cli_query_directory(
    2381           8 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    2382             :                 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
    2383             :                 talloc_tos(), &dir_data, &dir_data_length);
    2384             : 
    2385           8 :         if (!NT_STATUS_IS_OK(status)) {
    2386           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    2387           0 :                 return false;
    2388             :         }
    2389             : 
    2390           8 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    2391             :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    2392           8 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    2393           0 :                 printf("smb2cli_flush on a write-attributes directory "
    2394             :                         "returned %s\n",
    2395             :                         nt_errstr(status));
    2396           0 :                 return false;
    2397             :         }
    2398             : 
    2399           8 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2400             :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2401           8 :         if (!NT_STATUS_IS_OK(status)) {
    2402           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2403           0 :                 return false;
    2404             :         }
    2405             : 
    2406             :         /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
    2407             : 
    2408           8 :         status = smb2cli_create(
    2409             :                 cli->conn,
    2410           8 :                 cli->timeout,
    2411             :                 cli->smb2.session,
    2412             :                 cli->smb2.tcon,
    2413             :                 path,
    2414             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2415             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2416             :                 SEC_STD_SYNCHRONIZE|
    2417             :                 SEC_DIR_LIST|
    2418             :                 SEC_DIR_ADD_FILE, /* desired_access, */
    2419             :                 0, /* file_attributes, */
    2420             :                 FILE_SHARE_READ|
    2421             :                 FILE_SHARE_WRITE|
    2422             :                 FILE_SHARE_DELETE, /* share_access, */
    2423             :                 FILE_OPEN, /* create_disposition, */
    2424             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    2425             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2426             :                 NULL, /* smb2_create_blobs *blobs */
    2427             :                 &fid_persistent,
    2428             :                 &fid_volatile,
    2429             :                 NULL,
    2430             :                 NULL,
    2431             :                 NULL,
    2432             :                 NULL);
    2433           8 :         if (!NT_STATUS_IS_OK(status)) {
    2434           0 :                 printf("smb2cli_create '%s' (write FILE access) returned %s\n",
    2435             :                         path,
    2436             :                         nt_errstr(status));
    2437           0 :                 return false;
    2438             :         }
    2439             : 
    2440           8 :         status = smb2cli_query_directory(
    2441           8 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    2442             :                 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
    2443             :                 talloc_tos(), &dir_data, &dir_data_length);
    2444             : 
    2445           8 :         if (!NT_STATUS_IS_OK(status)) {
    2446           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    2447           0 :                 return false;
    2448             :         }
    2449             : 
    2450           8 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    2451             :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    2452           8 :         if (!NT_STATUS_IS_OK(status)) {
    2453           0 :                 printf("smb2cli_flush on a directory returned %s\n",
    2454             :                         nt_errstr(status));
    2455           0 :                 return false;
    2456             :         }
    2457             : 
    2458           8 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2459             :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2460           8 :         if (!NT_STATUS_IS_OK(status)) {
    2461           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2462           0 :                 return false;
    2463             :         }
    2464             : 
    2465             :         /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
    2466             : 
    2467           8 :         status = smb2cli_create(
    2468             :                 cli->conn,
    2469           8 :                 cli->timeout,
    2470             :                 cli->smb2.session,
    2471             :                 cli->smb2.tcon,
    2472             :                 path,
    2473             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2474             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2475             :                 SEC_STD_SYNCHRONIZE|
    2476             :                 SEC_DIR_LIST|
    2477             :                 SEC_DIR_ADD_SUBDIR, /* desired_access, */
    2478             :                 0, /* file_attributes, */
    2479             :                 FILE_SHARE_READ|
    2480             :                 FILE_SHARE_WRITE|
    2481             :                 FILE_SHARE_DELETE, /* share_access, */
    2482             :                 FILE_OPEN, /* create_disposition, */
    2483             :                 FILE_SYNCHRONOUS_IO_NONALERT|
    2484             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2485             :                 NULL, /* smb2_create_blobs *blobs */
    2486             :                 &fid_persistent,
    2487             :                 &fid_volatile,
    2488             :                 NULL,
    2489             :                 NULL,
    2490             :                 NULL,
    2491             :                 NULL);
    2492           8 :         if (!NT_STATUS_IS_OK(status)) {
    2493           0 :                 printf("smb2cli_create '%s' (write DIR access) returned %s\n",
    2494             :                         path,
    2495             :                         nt_errstr(status));
    2496           0 :                 return false;
    2497             :         }
    2498             : 
    2499           8 :         status = smb2cli_query_directory(
    2500           8 :                 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
    2501             :                 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
    2502             :                 talloc_tos(), &dir_data, &dir_data_length);
    2503             : 
    2504           8 :         if (!NT_STATUS_IS_OK(status)) {
    2505           0 :                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
    2506           0 :                 return false;
    2507             :         }
    2508             : 
    2509           8 :         status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
    2510             :                                cli->smb2.tcon, fid_persistent, fid_volatile);
    2511           8 :         if (!NT_STATUS_IS_OK(status)) {
    2512           0 :                 printf("smb2cli_flush on a directory returned %s\n",
    2513             :                         nt_errstr(status));
    2514           0 :                 return false;
    2515             :         }
    2516             : 
    2517           8 :         status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
    2518             :                                cli->smb2.tcon, 0, fid_persistent, fid_volatile);
    2519           8 :         if (!NT_STATUS_IS_OK(status)) {
    2520           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2521           0 :                 return false;
    2522             :         }
    2523             : 
    2524             : 
    2525           8 :         return true;
    2526             : }
    2527             : 
    2528           5 : bool run_smb2_dir_fsync(int dummy)
    2529             : {
    2530           5 :         struct cli_state *cli = NULL;
    2531           0 :         NTSTATUS status;
    2532           5 :         bool bret = false;
    2533           5 :         const char *dname = "fsync_test_dir";
    2534             : 
    2535           5 :         printf("Starting SMB2-DIR-FSYNC\n");
    2536             : 
    2537           5 :         if (!torture_init_connection(&cli)) {
    2538           0 :                 return false;
    2539             :         }
    2540             : 
    2541           5 :         status = smbXcli_negprot(cli->conn,
    2542           5 :                                  cli->timeout,
    2543             :                                  PROTOCOL_SMB2_02,
    2544             :                                  PROTOCOL_SMB2_02,
    2545             :                                  NULL,
    2546             :                                  NULL,
    2547             :                                  NULL);
    2548           5 :         if (!NT_STATUS_IS_OK(status)) {
    2549           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    2550           0 :                 return false;
    2551             :         }
    2552             : 
    2553           5 :         status = cli_session_setup_creds(cli, torture_creds);
    2554           5 :         if (!NT_STATUS_IS_OK(status)) {
    2555           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    2556           0 :                 return false;
    2557             :         }
    2558             : 
    2559           5 :         status = cli_tree_connect(cli, share, "?????", NULL);
    2560           5 :         if (!NT_STATUS_IS_OK(status)) {
    2561           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    2562           0 :                 return false;
    2563             :         }
    2564             : 
    2565           5 :         (void)cli_rmdir(cli, dname);
    2566           5 :         status = cli_mkdir(cli, dname);
    2567           5 :         if (!NT_STATUS_IS_OK(status)) {
    2568           0 :                 printf("cli_mkdir(%s) returned %s\n",
    2569             :                         dname,
    2570             :                         nt_errstr(status));
    2571           0 :                 return false;
    2572             :         }
    2573             : 
    2574             :         /* Test on a subdirectory. */
    2575           5 :         bret = test_dir_fsync(cli, dname);
    2576           5 :         if (bret == false) {
    2577           1 :                 (void)cli_rmdir(cli, dname);
    2578           1 :                 return false;
    2579             :         }
    2580           4 :         (void)cli_rmdir(cli, dname);
    2581             : 
    2582             :         /* Test on the root handle of a share. */
    2583           4 :         bret = test_dir_fsync(cli, "");
    2584           4 :         if (bret == false) {
    2585           0 :                 return false;
    2586             :         }
    2587           4 :         return true;
    2588             : }
    2589             : 
    2590           5 : bool run_smb2_path_slash(int dummy)
    2591             : {
    2592           5 :         struct cli_state *cli = NULL;
    2593           0 :         NTSTATUS status;
    2594           0 :         uint64_t fid_persistent;
    2595           0 :         uint64_t fid_volatile;
    2596           5 :         const char *dname_noslash = "smb2_dir_slash";
    2597           5 :         const char *dname_backslash = "smb2_dir_slash\\";
    2598           5 :         const char *dname_slash = "smb2_dir_slash/";
    2599           5 :         const char *fname_noslash = "smb2_file_slash";
    2600           5 :         const char *fname_backslash = "smb2_file_slash\\";
    2601           5 :         const char *fname_slash = "smb2_file_slash/";
    2602             : 
    2603           5 :         printf("Starting SMB2-PATH-SLASH\n");
    2604             : 
    2605           5 :         if (!torture_init_connection(&cli)) {
    2606           0 :                 return false;
    2607             :         }
    2608             : 
    2609           5 :         status = smbXcli_negprot(cli->conn,
    2610           5 :                                  cli->timeout,
    2611             :                                  PROTOCOL_SMB2_02,
    2612             :                                  PROTOCOL_SMB2_02,
    2613             :                                  NULL,
    2614             :                                  NULL,
    2615             :                                  NULL);
    2616           5 :         if (!NT_STATUS_IS_OK(status)) {
    2617           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    2618           0 :                 return false;
    2619             :         }
    2620             : 
    2621           5 :         status = cli_session_setup_creds(cli, torture_creds);
    2622           5 :         if (!NT_STATUS_IS_OK(status)) {
    2623           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    2624           0 :                 return false;
    2625             :         }
    2626             : 
    2627           5 :         status = cli_tree_connect(cli, share, "?????", NULL);
    2628           5 :         if (!NT_STATUS_IS_OK(status)) {
    2629           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    2630           0 :                 return false;
    2631             :         }
    2632             : 
    2633           5 :         (void)cli_unlink(cli, dname_noslash, 0);
    2634           5 :         (void)cli_rmdir(cli, dname_noslash);
    2635           5 :         (void)cli_unlink(cli, fname_noslash, 0);
    2636           5 :         (void)cli_rmdir(cli, fname_noslash);
    2637             : 
    2638             :         /* Try to create a directory with the backslash name. */
    2639           5 :         status = smb2cli_create(
    2640           5 :                 cli->conn,
    2641           5 :                 cli->timeout,
    2642           5 :                 cli->smb2.session,
    2643           5 :                 cli->smb2.tcon,
    2644             :                 dname_backslash,
    2645             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2646             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2647             :                 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
    2648             :                 0, /* file_attributes, */
    2649             :                 FILE_SHARE_READ|
    2650             :                 FILE_SHARE_WRITE|
    2651             :                 FILE_SHARE_DELETE, /* share_access, */
    2652             :                 FILE_CREATE, /* create_disposition, */
    2653             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2654             :                 NULL, /* smb2_create_blobs *blobs */
    2655             :                 &fid_persistent,
    2656             :                 &fid_volatile,
    2657             :                 NULL,
    2658             :                 NULL,
    2659             :                 NULL,
    2660             :                 NULL);
    2661             : 
    2662             :         /* directory ending in '\\' should be success. */
    2663             : 
    2664           5 :         if (!NT_STATUS_IS_OK(status)) {
    2665           0 :                 printf("smb2cli_create '%s' returned %s - "
    2666             :                         "should be NT_STATUS_OK\n",
    2667             :                         dname_backslash,
    2668             :                         nt_errstr(status));
    2669           0 :                 return false;
    2670             :         }
    2671           5 :         status = smb2cli_close(cli->conn,
    2672           5 :                                 cli->timeout,
    2673           5 :                                 cli->smb2.session,
    2674           5 :                                 cli->smb2.tcon,
    2675             :                                 0,
    2676             :                                 fid_persistent,
    2677             :                                 fid_volatile);
    2678           5 :         if (!NT_STATUS_IS_OK(status)) {
    2679           0 :                 printf("smb2cli_close returned %s\n", nt_errstr(status));
    2680           0 :                 return false;
    2681             :         }
    2682             : 
    2683           5 :         (void)cli_rmdir(cli, dname_noslash);
    2684             : 
    2685             :         /* Try to create a directory with the slash name. */
    2686           5 :         status = smb2cli_create(
    2687           5 :                 cli->conn,
    2688           5 :                 cli->timeout,
    2689           5 :                 cli->smb2.session,
    2690           5 :                 cli->smb2.tcon,
    2691             :                 dname_slash,
    2692             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2693             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2694             :                 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
    2695             :                 0, /* file_attributes, */
    2696             :                 FILE_SHARE_READ|
    2697             :                 FILE_SHARE_WRITE|
    2698             :                 FILE_SHARE_DELETE, /* share_access, */
    2699             :                 FILE_CREATE, /* create_disposition, */
    2700             :                 FILE_DIRECTORY_FILE, /* create_options, */
    2701             :                 NULL, /* smb2_create_blobs *blobs */
    2702             :                 &fid_persistent,
    2703             :                 &fid_volatile,
    2704             :                 NULL,
    2705             :                 NULL,
    2706             :                 NULL,
    2707             :                 NULL);
    2708             : 
    2709             :         /* directory ending in '/' is an error. */
    2710           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
    2711           0 :                 printf("smb2cli_create '%s' returned %s - "
    2712             :                         "should be NT_STATUS_OBJECT_NAME_INVALID\n",
    2713             :                         dname_slash,
    2714             :                         nt_errstr(status));
    2715           0 :                 if (NT_STATUS_IS_OK(status)) {
    2716           0 :                         (void)smb2cli_close(cli->conn,
    2717           0 :                                         cli->timeout,
    2718           0 :                                         cli->smb2.session,
    2719           0 :                                         cli->smb2.tcon,
    2720             :                                         0,
    2721             :                                         fid_persistent,
    2722             :                                         fid_volatile);
    2723             :                 }
    2724           0 :                 (void)cli_rmdir(cli, dname_noslash);
    2725           0 :                 return false;
    2726             :         }
    2727             : 
    2728           5 :         (void)cli_rmdir(cli, dname_noslash);
    2729             : 
    2730             :         /* Try to create a file with the backslash name. */
    2731           5 :         status = smb2cli_create(
    2732           5 :                 cli->conn,
    2733           5 :                 cli->timeout,
    2734           5 :                 cli->smb2.session,
    2735           5 :                 cli->smb2.tcon,
    2736             :                 fname_backslash,
    2737             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2738             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2739             :                 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
    2740             :                 0, /* file_attributes, */
    2741             :                 FILE_SHARE_READ|
    2742             :                 FILE_SHARE_WRITE|
    2743             :                 FILE_SHARE_DELETE, /* share_access, */
    2744             :                 FILE_CREATE, /* create_disposition, */
    2745             :                 FILE_NON_DIRECTORY_FILE, /* create_options, */
    2746             :                 NULL, /* smb2_create_blobs *blobs */
    2747             :                 &fid_persistent,
    2748             :                 &fid_volatile,
    2749             :                 NULL,
    2750             :                 NULL,
    2751             :                 NULL,
    2752             :                 NULL);
    2753             : 
    2754             :         /* file ending in '\\' should be error. */
    2755             : 
    2756           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
    2757           1 :                 printf("smb2cli_create '%s' returned %s - "
    2758             :                         "should be NT_STATUS_OBJECT_NAME_INVALID\n",
    2759             :                         fname_backslash,
    2760             :                         nt_errstr(status));
    2761           1 :                 if (NT_STATUS_IS_OK(status)) {
    2762           1 :                         (void)smb2cli_close(cli->conn,
    2763           1 :                                         cli->timeout,
    2764           1 :                                         cli->smb2.session,
    2765           1 :                                         cli->smb2.tcon,
    2766             :                                         0,
    2767             :                                         fid_persistent,
    2768             :                                         fid_volatile);
    2769             :                 }
    2770           1 :                 (void)cli_unlink(cli, fname_noslash, 0);
    2771           1 :                 return false;
    2772             :         }
    2773             : 
    2774           4 :         (void)cli_unlink(cli, fname_noslash, 0);
    2775             : 
    2776             :         /* Try to create a file with the slash name. */
    2777           4 :         status = smb2cli_create(
    2778           4 :                 cli->conn,
    2779           4 :                 cli->timeout,
    2780           4 :                 cli->smb2.session,
    2781           4 :                 cli->smb2.tcon,
    2782             :                 fname_slash,
    2783             :                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    2784             :                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    2785             :                 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
    2786             :                 0, /* file_attributes, */
    2787             :                 FILE_SHARE_READ|
    2788             :                 FILE_SHARE_WRITE|
    2789             :                 FILE_SHARE_DELETE, /* share_access, */
    2790             :                 FILE_CREATE, /* create_disposition, */
    2791             :                 FILE_NON_DIRECTORY_FILE, /* create_options, */
    2792             :                 NULL, /* smb2_create_blobs *blobs */
    2793             :                 &fid_persistent,
    2794             :                 &fid_volatile,
    2795             :                 NULL,
    2796             :                 NULL,
    2797             :                 NULL,
    2798             :                 NULL);
    2799             : 
    2800             :         /* file ending in '/' should be error. */
    2801             : 
    2802           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
    2803           0 :                 printf("smb2cli_create '%s' returned %s - "
    2804             :                         "should be NT_STATUS_OBJECT_NAME_INVALID\n",
    2805             :                         fname_slash,
    2806             :                         nt_errstr(status));
    2807           0 :                 if (NT_STATUS_IS_OK(status)) {
    2808           0 :                         (void)smb2cli_close(cli->conn,
    2809           0 :                                         cli->timeout,
    2810           0 :                                         cli->smb2.session,
    2811           0 :                                         cli->smb2.tcon,
    2812             :                                         0,
    2813             :                                         fid_persistent,
    2814             :                                         fid_volatile);
    2815             :                 }
    2816           0 :                 (void)cli_unlink(cli, fname_noslash, 0);
    2817           0 :                 return false;
    2818             :         }
    2819             : 
    2820           4 :         (void)cli_unlink(cli, fname_noslash, 0);
    2821           4 :         return true;
    2822             : }
    2823             : 
    2824             : /*
    2825             :  * NB. This can only work against a server where
    2826             :  * the connecting user has been granted SeSecurityPrivilege.
    2827             :  *
    2828             :  *  1). Create a test file.
    2829             :  *  2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
    2830             :  *             NB. SMB2-only behavior.
    2831             :  *  3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
    2832             :  *  4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
    2833             :  *  5). Close (3).
    2834             :  *  6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
    2835             :  *  7). Write SACL. Success.
    2836             :  *  8). Close (4).
    2837             :  *  9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
    2838             :  *  10). Read SACL. Success.
    2839             :  *  11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
    2840             :  *  12). Close (9).
    2841             :  */
    2842             : 
    2843           2 : bool run_smb2_sacl(int dummy)
    2844             : {
    2845           2 :         struct cli_state *cli = NULL;
    2846           0 :         NTSTATUS status;
    2847           2 :         struct security_descriptor *sd_dacl = NULL;
    2848           2 :         struct security_descriptor *sd_sacl = NULL;
    2849           2 :         const char *fname = "sacl_test_file";
    2850           2 :         uint16_t fnum = (uint16_t)-1;
    2851             : 
    2852           2 :         printf("Starting SMB2-SACL\n");
    2853             : 
    2854           2 :         if (!torture_init_connection(&cli)) {
    2855           0 :                 return false;
    2856             :         }
    2857             : 
    2858           2 :         status = smbXcli_negprot(cli->conn,
    2859           2 :                                  cli->timeout,
    2860             :                                  PROTOCOL_SMB2_02,
    2861             :                                  PROTOCOL_SMB3_11,
    2862             :                                  NULL,
    2863             :                                  NULL,
    2864             :                                  NULL);
    2865           2 :         if (!NT_STATUS_IS_OK(status)) {
    2866           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    2867           0 :                 return false;
    2868             :         }
    2869             : 
    2870           2 :         status = cli_session_setup_creds(cli, torture_creds);
    2871           2 :         if (!NT_STATUS_IS_OK(status)) {
    2872           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    2873           0 :                 return false;
    2874             :         }
    2875             : 
    2876           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    2877           2 :         if (!NT_STATUS_IS_OK(status)) {
    2878           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    2879           0 :                 return false;
    2880             :         }
    2881             : 
    2882           2 :         (void)cli_unlink(cli, fname, 0);
    2883             : 
    2884             :         /* First create a file. */
    2885           2 :         status = cli_ntcreate(cli,
    2886             :                                 fname,
    2887             :                                 0,
    2888             :                                 GENERIC_ALL_ACCESS,
    2889             :                                 FILE_ATTRIBUTE_NORMAL,
    2890             :                                 FILE_SHARE_NONE,
    2891             :                                 FILE_CREATE,
    2892             :                                 0,
    2893             :                                 0,
    2894             :                                 &fnum,
    2895             :                                 NULL);
    2896             : 
    2897           2 :         if (!NT_STATUS_IS_OK(status)) {
    2898           0 :                 printf("Create of %s failed (%s)\n",
    2899             :                         fname,
    2900             :                         nt_errstr(status));
    2901           0 :                 goto fail;
    2902             :         }
    2903             : 
    2904           2 :         cli_close(cli, fnum);
    2905           2 :         fnum = (uint16_t)-1;
    2906             : 
    2907             :         /*
    2908             :          * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
    2909             :          * This should fail with NT_STATUS_ACCESS_DENIED - but
    2910             :          * only against an SMB2 server. SMB1 allows this as tested
    2911             :          * in SMB1-SYSTEM-SECURITY.
    2912             :          */
    2913             : 
    2914           2 :         status = cli_smb2_create_fnum(cli,
    2915             :                         fname,
    2916           2 :                         (struct cli_smb2_create_flags){0},
    2917             :                         SMB2_IMPERSONATION_IMPERSONATION,
    2918             :                         SEC_FLAG_SYSTEM_SECURITY, /* desired access */
    2919             :                         0, /* file_attributes, */
    2920             :                         FILE_SHARE_READ|
    2921             :                                 FILE_SHARE_WRITE|
    2922             :                                 FILE_SHARE_DELETE, /* share_access, */
    2923             :                         FILE_OPEN, /* create_disposition, */
    2924             :                         FILE_NON_DIRECTORY_FILE, /* create_options, */
    2925             :                         NULL, /* in_cblobs. */
    2926             :                         &fnum, /* fnum */
    2927             :                         NULL, /* smb_create_returns  */
    2928             :                         talloc_tos(), /* mem_ctx */
    2929             :                         NULL); /* out_cblobs */
    2930             : 
    2931           2 :         if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
    2932           0 :                 printf("SMB2-SACL-TEST can only work with a user "
    2933             :                         "who has been granted SeSecurityPrivilege.\n"
    2934             :                         "This is the "
    2935             :                         "\"Manage auditing and security log\""
    2936             :                         "privilege setting on Windows\n");
    2937           0 :                 goto fail;
    2938             :         }
    2939             : 
    2940           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    2941           0 :                 printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
    2942             :                         "got %s - should fail with ACCESS_DENIED\n",
    2943             :                         fname,
    2944             :                         nt_errstr(status));
    2945           0 :                 goto fail;
    2946             :         }
    2947             : 
    2948             :         /*
    2949             :          * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
    2950             :          */
    2951             : 
    2952           2 :         status = cli_smb2_create_fnum(cli,
    2953             :                         fname,
    2954           2 :                         (struct cli_smb2_create_flags){0},
    2955             :                         SMB2_IMPERSONATION_IMPERSONATION,
    2956             :                         SEC_FLAG_SYSTEM_SECURITY|
    2957             :                                 FILE_WRITE_ATTRIBUTES, /* desired access */
    2958             :                         0, /* file_attributes, */
    2959             :                         FILE_SHARE_READ|
    2960             :                                 FILE_SHARE_WRITE|
    2961             :                                 FILE_SHARE_DELETE, /* share_access, */
    2962             :                         FILE_OPEN, /* create_disposition, */
    2963             :                         FILE_NON_DIRECTORY_FILE, /* create_options, */
    2964             :                         NULL, /* in_cblobs. */
    2965             :                         &fnum, /* fnum */
    2966             :                         NULL, /* smb_create_returns  */
    2967             :                         talloc_tos(), /* mem_ctx */
    2968             :                         NULL); /* out_cblobs */
    2969             : 
    2970           2 :         if (!NT_STATUS_IS_OK(status)) {
    2971           0 :                 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
    2972             :                         "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
    2973             :                         fname,
    2974             :                         nt_errstr(status));
    2975           0 :                 goto fail;
    2976             :         }
    2977             : 
    2978             :         /* Create an SD with a SACL. */
    2979           2 :         sd_sacl = security_descriptor_sacl_create(talloc_tos(),
    2980             :                                 0,
    2981             :                                 NULL, /* owner. */
    2982             :                                 NULL, /* group. */
    2983             :                                 /* first ACE. */
    2984             :                                 SID_WORLD,
    2985             :                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
    2986             :                                 SEC_GENERIC_ALL,
    2987             :                                 SEC_ACE_FLAG_FAILED_ACCESS,
    2988             :                                 NULL);
    2989             : 
    2990           2 :         if (sd_sacl == NULL) {
    2991           0 :                 printf("Out of memory creating SACL\n");
    2992           0 :                 goto fail;
    2993             :         }
    2994             : 
    2995             :         /*
    2996             :          * Write the SACL SD. This should fail
    2997             :          * even though we have SEC_FLAG_SYSTEM_SECURITY,
    2998             :          * as it seems to also need WRITE_DAC access.
    2999             :          */
    3000           2 :         status = cli_set_security_descriptor(cli,
    3001             :                                 fnum,
    3002             :                                 SECINFO_DACL|SECINFO_SACL,
    3003             :                                 sd_sacl);
    3004             : 
    3005           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    3006           0 :                 printf("Writing SACL on file %s got (%s) "
    3007             :                         "should have failed with ACCESS_DENIED.\n",
    3008             :                         fname,
    3009             :                         nt_errstr(status));
    3010           0 :                 goto fail;
    3011             :         }
    3012             : 
    3013             :         /* And close. */
    3014           2 :         cli_smb2_close_fnum(cli, fnum);
    3015           2 :         fnum = (uint16_t)-1;
    3016             : 
    3017             :         /*
    3018             :          * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
    3019             :          */
    3020             : 
    3021           2 :         status = cli_smb2_create_fnum(cli,
    3022             :                         fname,
    3023           2 :                         (struct cli_smb2_create_flags){0},
    3024             :                         SMB2_IMPERSONATION_IMPERSONATION,
    3025             :                         SEC_FLAG_SYSTEM_SECURITY|
    3026             :                                 SEC_STD_WRITE_DAC, /* desired access */
    3027             :                         0, /* file_attributes, */
    3028             :                         FILE_SHARE_READ|
    3029             :                                 FILE_SHARE_WRITE|
    3030             :                                 FILE_SHARE_DELETE, /* share_access, */
    3031             :                         FILE_OPEN, /* create_disposition, */
    3032             :                         FILE_NON_DIRECTORY_FILE, /* create_options, */
    3033             :                         NULL, /* in_cblobs. */
    3034             :                         &fnum, /* fnum */
    3035             :                         NULL, /* smb_create_returns  */
    3036             :                         talloc_tos(), /* mem_ctx */
    3037             :                         NULL); /* out_cblobs */
    3038             : 
    3039           2 :         if (!NT_STATUS_IS_OK(status)) {
    3040           0 :                 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
    3041             :                         "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
    3042             :                         fname,
    3043             :                         nt_errstr(status));
    3044           0 :                 goto fail;
    3045             :         }
    3046             : 
    3047             :         /*
    3048             :          * Write the SACL SD. This should now succeed
    3049             :          * as we have both SEC_FLAG_SYSTEM_SECURITY
    3050             :          * and WRITE_DAC access.
    3051             :          */
    3052           2 :         status = cli_set_security_descriptor(cli,
    3053             :                                 fnum,
    3054             :                                 SECINFO_DACL|SECINFO_SACL,
    3055             :                                 sd_sacl);
    3056             : 
    3057           2 :         if (!NT_STATUS_IS_OK(status)) {
    3058           0 :                 printf("cli_set_security_descriptor SACL "
    3059             :                         "on file %s failed (%s)\n",
    3060             :                         fname,
    3061             :                         nt_errstr(status));
    3062           0 :                 goto fail;
    3063             :         }
    3064             : 
    3065             :         /* And close. */
    3066           2 :         cli_smb2_close_fnum(cli, fnum);
    3067           2 :         fnum = (uint16_t)-1;
    3068             : 
    3069             :         /* We're done with the sacl we made. */
    3070           2 :         TALLOC_FREE(sd_sacl);
    3071             : 
    3072             :         /*
    3073             :          * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
    3074             :          * This gives us access to the SACL.
    3075             :          */
    3076             : 
    3077           2 :         status = cli_smb2_create_fnum(cli,
    3078             :                         fname,
    3079           2 :                         (struct cli_smb2_create_flags){0},
    3080             :                         SMB2_IMPERSONATION_IMPERSONATION,
    3081             :                         SEC_FLAG_SYSTEM_SECURITY|
    3082             :                                 FILE_READ_ATTRIBUTES, /* desired access */
    3083             :                         0, /* file_attributes, */
    3084             :                         FILE_SHARE_READ|
    3085             :                                 FILE_SHARE_WRITE|
    3086             :                                 FILE_SHARE_DELETE, /* share_access, */
    3087             :                         FILE_OPEN, /* create_disposition, */
    3088             :                         FILE_NON_DIRECTORY_FILE, /* create_options, */
    3089             :                         NULL, /* in_cblobs. */
    3090             :                         &fnum, /* fnum */
    3091             :                         NULL, /* smb_create_returns  */
    3092             :                         talloc_tos(), /* mem_ctx */
    3093             :                         NULL); /* out_cblobs */
    3094             : 
    3095           2 :         if (!NT_STATUS_IS_OK(status)) {
    3096           0 :                 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
    3097             :                         "FILE_READ_ATTRIBUTES) failed (%s)\n",
    3098             :                         fname,
    3099             :                         nt_errstr(status));
    3100           0 :                 goto fail;
    3101             :         }
    3102             : 
    3103             :         /* Try and read the SACL - should succeed. */
    3104           2 :         status = cli_query_security_descriptor(
    3105             :                 cli, fnum, SECINFO_SACL, talloc_tos(), &sd_sacl);
    3106             : 
    3107           2 :         if (!NT_STATUS_IS_OK(status)) {
    3108           0 :                 printf("Read SACL from file %s failed (%s)\n",
    3109             :                         fname,
    3110             :                         nt_errstr(status));
    3111           0 :                 goto fail;
    3112             :         }
    3113             : 
    3114           2 :         TALLOC_FREE(sd_sacl);
    3115             : 
    3116             :         /*
    3117             :          * Try and read the DACL - should fail as we have
    3118             :          * no READ_DAC access.
    3119             :          */
    3120           2 :         status = cli_query_security_descriptor(
    3121             :                 cli, fnum, SECINFO_DACL, talloc_tos(), &sd_sacl);
    3122             : 
    3123           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    3124           0 :                 printf("Reading DACL on file %s got (%s) "
    3125             :                         "should have failed with ACCESS_DENIED.\n",
    3126             :                         fname,
    3127             :                         nt_errstr(status));
    3128           0 :                 goto fail;
    3129             :         }
    3130             : 
    3131           2 :         if (fnum != (uint16_t)-1) {
    3132           2 :                 cli_smb2_close_fnum(cli, fnum);
    3133           2 :                 fnum = (uint16_t)-1;
    3134             :         }
    3135             : 
    3136           2 :         TALLOC_FREE(sd_dacl);
    3137           2 :         TALLOC_FREE(sd_sacl);
    3138             : 
    3139           2 :         (void)cli_unlink(cli, fname, 0);
    3140           2 :         return true;
    3141             : 
    3142           0 :   fail:
    3143             : 
    3144           0 :         TALLOC_FREE(sd_dacl);
    3145           0 :         TALLOC_FREE(sd_sacl);
    3146             : 
    3147           0 :         if (fnum != (uint16_t)-1) {
    3148           0 :                 cli_smb2_close_fnum(cli, fnum);
    3149           0 :                 fnum = (uint16_t)-1;
    3150             :         }
    3151             : 
    3152           0 :         (void)cli_unlink(cli, fname, 0);
    3153           0 :         return false;
    3154             : }
    3155             : 
    3156           5 : bool run_smb2_quota1(int dummy)
    3157             : {
    3158           5 :         struct cli_state *cli = NULL;
    3159           0 :         NTSTATUS status;
    3160           5 :         uint16_t fnum = (uint16_t)-1;
    3161           5 :         SMB_NTQUOTA_STRUCT qt = {0};
    3162             : 
    3163           5 :         printf("Starting SMB2-QUOTA1\n");
    3164             : 
    3165           5 :         if (!torture_init_connection(&cli)) {
    3166           0 :                 return false;
    3167             :         }
    3168             : 
    3169           5 :         status = smbXcli_negprot(cli->conn,
    3170           5 :                                  cli->timeout,
    3171             :                                  PROTOCOL_SMB2_02,
    3172             :                                  PROTOCOL_SMB3_11,
    3173             :                                  NULL,
    3174             :                                  NULL,
    3175             :                                  NULL);
    3176           5 :         if (!NT_STATUS_IS_OK(status)) {
    3177           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3178           0 :                 return false;
    3179             :         }
    3180             : 
    3181           5 :         status = cli_session_setup_creds(cli, torture_creds);
    3182           5 :         if (!NT_STATUS_IS_OK(status)) {
    3183           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3184           0 :                 return false;
    3185             :         }
    3186             : 
    3187           5 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3188           5 :         if (!NT_STATUS_IS_OK(status)) {
    3189           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3190           0 :                 return false;
    3191             :         }
    3192             : 
    3193           5 :         status = cli_smb2_create_fnum(
    3194             :                 cli,
    3195             :                 "\\",
    3196           5 :                 (struct cli_smb2_create_flags){0},
    3197             :                 SMB2_IMPERSONATION_IMPERSONATION,
    3198             :                 SEC_GENERIC_READ, /* desired access */
    3199             :                 0, /* file_attributes, */
    3200             :                 FILE_SHARE_READ|
    3201             :                 FILE_SHARE_WRITE|
    3202             :                 FILE_SHARE_DELETE, /* share_access, */
    3203             :                 FILE_OPEN, /* create_disposition, */
    3204             :                 FILE_DIRECTORY_FILE, /* create_options, */
    3205             :                 NULL, /* in_cblobs. */
    3206             :                 &fnum, /* fnum */
    3207             :                 NULL, /* smb_create_returns  */
    3208             :                 NULL, /* mem_ctx */
    3209             :                 NULL); /* out_cblobs */
    3210           5 :         if (!NT_STATUS_IS_OK(status)) {
    3211           0 :                 printf("cli_smb2_create_fnum failed: %s\n", nt_errstr(status));
    3212           0 :                 return false;
    3213             :         }
    3214             : 
    3215           5 :         status = cli_smb2_get_user_quota(cli, fnum, &qt);
    3216           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
    3217           1 :                 printf("cli_smb2_get_user_quota returned %s, expected "
    3218             :                        "NT_STATUS_INVALID_HANDLE\n",
    3219             :                        nt_errstr(status));
    3220           1 :                 return false;
    3221             :         }
    3222             : 
    3223           4 :         return true;
    3224             : }
    3225             : 
    3226           2 : bool run_smb2_stream_acl(int dummy)
    3227             : {
    3228           2 :         struct cli_state *cli = NULL;
    3229           0 :         NTSTATUS status;
    3230           2 :         uint16_t fnum = (uint16_t)-1;
    3231           2 :         const char *fname = "stream_acl_test_file";
    3232           2 :         const char *sname = "stream_acl_test_file:streamname";
    3233           2 :         struct security_descriptor *sd_dacl = NULL;
    3234           2 :         bool ret = false;
    3235             : 
    3236           2 :         printf("SMB2 stream acl\n");
    3237             : 
    3238           2 :         if (!torture_init_connection(&cli)) {
    3239           0 :                 return false;
    3240             :         }
    3241             : 
    3242           2 :         status = smbXcli_negprot(cli->conn,
    3243           2 :                                  cli->timeout,
    3244             :                                  PROTOCOL_SMB2_02,
    3245             :                                  PROTOCOL_SMB3_11,
    3246             :                                  NULL,
    3247             :                                  NULL,
    3248             :                                  NULL);
    3249           2 :         if (!NT_STATUS_IS_OK(status)) {
    3250           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3251           0 :                 return false;
    3252             :         }
    3253             : 
    3254           2 :         status = cli_session_setup_creds(cli, torture_creds);
    3255           2 :         if (!NT_STATUS_IS_OK(status)) {
    3256           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3257           0 :                 return false;
    3258             :         }
    3259             : 
    3260           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3261           2 :         if (!NT_STATUS_IS_OK(status)) {
    3262           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3263           0 :                 return false;
    3264             :         }
    3265             : 
    3266             :         /* Ensure file doesn't exist. */
    3267           2 :         (void)cli_unlink(cli, fname, 0);
    3268             : 
    3269             :         /* Create the file. */
    3270           2 :         status = cli_ntcreate(cli,
    3271             :                                 fname,
    3272             :                                 0,
    3273             :                                 GENERIC_ALL_ACCESS,
    3274             :                                 FILE_ATTRIBUTE_NORMAL,
    3275             :                                 FILE_SHARE_NONE,
    3276             :                                 FILE_CREATE,
    3277             :                                 0,
    3278             :                                 0,
    3279             :                                 &fnum,
    3280             :                                 NULL);
    3281             : 
    3282           2 :         if (!NT_STATUS_IS_OK(status)) {
    3283           0 :                 printf("Create of %s failed (%s)\n",
    3284             :                         fname,
    3285             :                         nt_errstr(status));
    3286           0 :                 goto fail;
    3287             :         }
    3288             : 
    3289             :         /* Close the handle. */
    3290           2 :         cli_smb2_close_fnum(cli, fnum);
    3291           2 :         fnum = (uint16_t)-1;
    3292             : 
    3293             :         /* Create the stream. */
    3294           2 :         status = cli_ntcreate(cli,
    3295             :                                 sname,
    3296             :                                 0,
    3297             :                                 FILE_READ_DATA|
    3298             :                                         SEC_STD_READ_CONTROL|
    3299             :                                         SEC_STD_WRITE_DAC,
    3300             :                                 FILE_ATTRIBUTE_NORMAL,
    3301             :                                 FILE_SHARE_NONE,
    3302             :                                 FILE_CREATE,
    3303             :                                 0,
    3304             :                                 0,
    3305             :                                 &fnum,
    3306             :                                 NULL);
    3307             : 
    3308           2 :         if (!NT_STATUS_IS_OK(status)) {
    3309           0 :                 printf("Create of %s failed (%s)\n",
    3310             :                         sname,
    3311             :                         nt_errstr(status));
    3312           0 :                 goto fail;
    3313             :         }
    3314             : 
    3315             :         /* Close the handle. */
    3316           2 :         cli_smb2_close_fnum(cli, fnum);
    3317           2 :         fnum = (uint16_t)-1;
    3318             : 
    3319             :         /*
    3320             :          * Open the stream - for Samba this ensures
    3321             :          * we prove we have a pathref fsp.
    3322             :          */
    3323           2 :         status = cli_ntcreate(cli,
    3324             :                                 sname,
    3325             :                                 0,
    3326             :                                 FILE_READ_DATA|
    3327             :                                         SEC_STD_READ_CONTROL|
    3328             :                                         SEC_STD_WRITE_DAC,
    3329             :                                 FILE_ATTRIBUTE_NORMAL,
    3330             :                                 FILE_SHARE_NONE,
    3331             :                                 FILE_OPEN,
    3332             :                                 0,
    3333             :                                 0,
    3334             :                                 &fnum,
    3335             :                                 NULL);
    3336             : 
    3337           2 :         if (!NT_STATUS_IS_OK(status)) {
    3338           0 :                 printf("Open of %s failed (%s)\n",
    3339             :                         sname,
    3340             :                         nt_errstr(status));
    3341           0 :                 goto fail;
    3342             :         }
    3343             : 
    3344             :         /* Read the security descriptor off the stream handle. */
    3345           2 :         status = cli_query_security_descriptor(cli,
    3346             :                                 fnum,
    3347             :                                 SECINFO_DACL,
    3348             :                                 talloc_tos(),
    3349             :                                 &sd_dacl);
    3350             : 
    3351           2 :         if (!NT_STATUS_IS_OK(status)) {
    3352           0 :                 printf("Reading DACL on stream %s got (%s)\n",
    3353             :                         sname,
    3354             :                         nt_errstr(status));
    3355           0 :                 goto fail;
    3356             :         }
    3357             : 
    3358           2 :         if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
    3359           2 :                         sd_dacl->dacl->num_aces < 1) {
    3360           0 :                 printf("Invalid DACL returned on stream %s "
    3361             :                         "(this should not happen)\n",
    3362             :                         sname);
    3363           0 :                 goto fail;
    3364             :         }
    3365             : 
    3366             :         /*
    3367             :          * Ensure it allows FILE_READ_DATA in the first ace.
    3368             :          * It always should.
    3369             :          */
    3370           2 :         if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
    3371           0 :                 printf("DACL->ace[0] returned on stream %s "
    3372             :                         "doesn't have read access (should not happen)\n",
    3373             :                         sname);
    3374           0 :                 goto fail;
    3375             :         }
    3376             : 
    3377             :         /* Remove FILE_READ_DATA from the first ace and set. */
    3378           2 :         sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
    3379             : 
    3380           2 :         status = cli_set_security_descriptor(cli,
    3381             :                                 fnum,
    3382             :                                 SECINFO_DACL,
    3383             :                                 sd_dacl);
    3384             : 
    3385           2 :         if (!NT_STATUS_IS_OK(status)) {
    3386           0 :                 printf("Setting DACL on stream %s got (%s)\n",
    3387             :                         sname,
    3388             :                         nt_errstr(status));
    3389           0 :                 goto fail;
    3390             :         }
    3391             : 
    3392           2 :         TALLOC_FREE(sd_dacl);
    3393             : 
    3394             :         /* Read again and check it changed. */
    3395           2 :         status = cli_query_security_descriptor(cli,
    3396             :                                 fnum,
    3397             :                                 SECINFO_DACL,
    3398             :                                 talloc_tos(),
    3399             :                                 &sd_dacl);
    3400             : 
    3401           2 :         if (!NT_STATUS_IS_OK(status)) {
    3402           0 :                 printf("Reading DACL on stream %s got (%s)\n",
    3403             :                         sname,
    3404             :                         nt_errstr(status));
    3405           0 :                 goto fail;
    3406             :         }
    3407             : 
    3408           2 :         if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
    3409           2 :                         sd_dacl->dacl->num_aces < 1) {
    3410           0 :                 printf("Invalid DACL (1) returned on stream %s "
    3411             :                         "(this should not happen)\n",
    3412             :                         sname);
    3413           0 :                 goto fail;
    3414             :         }
    3415             : 
    3416             :         /* FILE_READ_DATA should be gone from the first ace. */
    3417           2 :         if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
    3418           0 :                 printf("DACL on stream %s did not change\n",
    3419             :                         sname);
    3420           0 :                 goto fail;
    3421             :         }
    3422             : 
    3423           2 :         ret = true;
    3424             : 
    3425           2 :   fail:
    3426             : 
    3427           2 :         if (fnum != (uint16_t)-1) {
    3428           2 :                 cli_smb2_close_fnum(cli, fnum);
    3429           2 :                 fnum = (uint16_t)-1;
    3430             :         }
    3431             : 
    3432           2 :         (void)cli_unlink(cli, fname, 0);
    3433           2 :         return ret;
    3434             : }
    3435             : 
    3436           2 : static NTSTATUS list_fn(struct file_info *finfo,
    3437             :                         const char *name,
    3438             :                         void *state)
    3439             : {
    3440           2 :         bool *matched = (bool *)state;
    3441           2 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    3442           2 :                 *matched = true;
    3443             :         }
    3444           2 :         return NT_STATUS_OK;
    3445             : }
    3446             : 
    3447             : /*
    3448             :  * Must be run against a share with "smbd async dosmode = yes".
    3449             :  * Checks we can return DOS attriutes other than "N".
    3450             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14758
    3451             :  */
    3452             : 
    3453           2 : bool run_list_dir_async_test(int dummy)
    3454             : {
    3455           2 :         struct cli_state *cli = NULL;
    3456           0 :         NTSTATUS status;
    3457           2 :         const char *dname = "ASYNC_DIR";
    3458           2 :         bool ret = false;
    3459           2 :         bool matched = false;
    3460             : 
    3461           2 :         printf("SMB2 list dir async\n");
    3462             : 
    3463           2 :         if (!torture_init_connection(&cli)) {
    3464           0 :                 return false;
    3465             :         }
    3466             : 
    3467           2 :         status = smbXcli_negprot(cli->conn,
    3468           2 :                                  cli->timeout,
    3469             :                                  PROTOCOL_SMB2_02,
    3470             :                                  PROTOCOL_SMB3_11,
    3471             :                                  NULL,
    3472             :                                  NULL,
    3473             :                                  NULL);
    3474           2 :         if (!NT_STATUS_IS_OK(status)) {
    3475           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3476           0 :                 return false;
    3477             :         }
    3478             : 
    3479           2 :         status = cli_session_setup_creds(cli, torture_creds);
    3480           2 :         if (!NT_STATUS_IS_OK(status)) {
    3481           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3482           0 :                 return false;
    3483             :         }
    3484             : 
    3485           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3486           2 :         if (!NT_STATUS_IS_OK(status)) {
    3487           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3488           0 :                 return false;
    3489             :         }
    3490             : 
    3491             :         /* Ensure directory doesn't exist. */
    3492           2 :         (void)cli_rmdir(cli, dname);
    3493             : 
    3494           2 :         status = cli_mkdir(cli, dname);
    3495           2 :         if (!NT_STATUS_IS_OK(status)) {
    3496           0 :                 printf("cli_mkdir %s returned %s\n", dname, nt_errstr(status));
    3497           0 :                 return false;
    3498             :         }
    3499             : 
    3500           2 :         status = cli_list(cli,
    3501             :                           dname,
    3502             :                           FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_DIRECTORY,
    3503             :                           list_fn,
    3504             :                           &matched);
    3505           2 :         if (!NT_STATUS_IS_OK(status)) {
    3506           0 :                 printf("cli_list %s returned %s\n", dname, nt_errstr(status));
    3507           0 :                 goto fail;
    3508             :         }
    3509             : 
    3510           2 :         if (!matched) {
    3511           0 :                 printf("Failed to find %s\n", dname);
    3512           0 :                 goto fail;
    3513             :         }
    3514             : 
    3515           2 :         ret = true;
    3516             : 
    3517           2 :   fail:
    3518             : 
    3519           2 :         (void)cli_rmdir(cli, dname);
    3520           2 :         return ret;
    3521             : }
    3522             : 
    3523             : /*
    3524             :  * Test delete a directory fails if a file is created
    3525             :  * in a directory after the delete on close is set.
    3526             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
    3527             :  */
    3528             : 
    3529           2 : bool run_delete_on_close_non_empty(int dummy)
    3530             : {
    3531           2 :         struct cli_state *cli = NULL;
    3532           0 :         NTSTATUS status;
    3533           2 :         const char *dname = "DEL_ON_CLOSE_DIR";
    3534           2 :         const char *fname = "DEL_ON_CLOSE_DIR\\testfile";
    3535           2 :         uint16_t fnum = (uint16_t)-1;
    3536           2 :         uint16_t fnum1 = (uint16_t)-1;
    3537           2 :         bool ret = false;
    3538             : 
    3539           2 :         printf("SMB2 delete on close nonempty\n");
    3540             : 
    3541           2 :         if (!torture_init_connection(&cli)) {
    3542           0 :                 return false;
    3543             :         }
    3544             : 
    3545           2 :         status = smbXcli_negprot(cli->conn,
    3546           2 :                                  cli->timeout,
    3547             :                                  PROTOCOL_SMB2_02,
    3548             :                                  PROTOCOL_SMB3_11,
    3549             :                                  NULL,
    3550             :                                  NULL,
    3551             :                                  NULL);
    3552           2 :         if (!NT_STATUS_IS_OK(status)) {
    3553           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3554           0 :                 return false;
    3555             :         }
    3556             : 
    3557           2 :         status = cli_session_setup_creds(cli, torture_creds);
    3558           2 :         if (!NT_STATUS_IS_OK(status)) {
    3559           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3560           0 :                 return false;
    3561             :         }
    3562             : 
    3563           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3564           2 :         if (!NT_STATUS_IS_OK(status)) {
    3565           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3566           0 :                 return false;
    3567             :         }
    3568             : 
    3569             :         /* Ensure directory doesn't exist. */
    3570           2 :         (void)cli_unlink(cli,
    3571             :                          fname,
    3572             :                          FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3573           2 :         (void)cli_rmdir(cli, dname);
    3574             : 
    3575             :         /* Create target directory. */
    3576           2 :         status = cli_ntcreate(cli,
    3577             :                                 dname,
    3578             :                                 0,
    3579             :                                 DELETE_ACCESS|FILE_READ_DATA,
    3580             :                                 FILE_ATTRIBUTE_DIRECTORY,
    3581             :                                 FILE_SHARE_READ|
    3582             :                                         FILE_SHARE_WRITE|
    3583             :                                         FILE_SHARE_DELETE,
    3584             :                                 FILE_CREATE,
    3585             :                                 FILE_DIRECTORY_FILE,
    3586             :                                 0,
    3587             :                                 &fnum,
    3588             :                                 NULL);
    3589           2 :         if (!NT_STATUS_IS_OK(status)) {
    3590           0 :                 printf("cli_ntcreate for directory %s returned %s\n",
    3591             :                                 dname,
    3592             :                                 nt_errstr(status));
    3593           0 :                 goto out;
    3594             :         }
    3595             : 
    3596             :         /* Now set the delete on close bit. */
    3597           2 :         status = cli_nt_delete_on_close(cli, fnum, 1);
    3598           2 :         if (!NT_STATUS_IS_OK(status)) {
    3599           0 :                 printf("cli_cli_nt_delete_on_close set for directory "
    3600             :                         "%s returned %s\n",
    3601             :                         dname,
    3602             :                         nt_errstr(status));
    3603           0 :                 goto out;
    3604             :         }
    3605             : 
    3606             :         /* Create file inside target directory. */
    3607             :         /*
    3608             :          * NB. On Windows this will return NT_STATUS_DELETE_PENDING.  Only on
    3609             :          * Samba will this succeed by default (the option "check parent
    3610             :          * directory delete on close" configures behaviour), but we're using
    3611             :          * this to test a race condition.
    3612             :          */
    3613           2 :         status = cli_ntcreate(cli,
    3614             :                                 fname,
    3615             :                                 0,
    3616             :                                 FILE_READ_DATA,
    3617             :                                 FILE_ATTRIBUTE_NORMAL,
    3618             :                                 FILE_SHARE_READ|
    3619             :                                         FILE_SHARE_WRITE|
    3620             :                                         FILE_SHARE_DELETE,
    3621             :                                 FILE_CREATE,
    3622             :                                 0,
    3623             :                                 0,
    3624             :                                 &fnum1,
    3625             :                                 NULL);
    3626           2 :         if (!NT_STATUS_IS_OK(status)) {
    3627           0 :                 printf("cli_ntcreate for file %s returned %s\n",
    3628             :                                 fname,
    3629             :                                 nt_errstr(status));
    3630           0 :                 goto out;
    3631             :         }
    3632           2 :         cli_close(cli, fnum1);
    3633           2 :         fnum1 = (uint16_t)-1;
    3634             : 
    3635             :         /* Now the close should fail. */
    3636           2 :         status = cli_close(cli, fnum);
    3637           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
    3638           0 :                 printf("cli_close for directory %s returned %s\n",
    3639             :                                 dname,
    3640             :                                 nt_errstr(status));
    3641           0 :                 goto out;
    3642             :         }
    3643             : 
    3644           2 :         ret = true;
    3645             : 
    3646           2 :   out:
    3647             : 
    3648           2 :         if (fnum1 != (uint16_t)-1) {
    3649           0 :                 cli_close(cli, fnum1);
    3650             :         }
    3651           2 :         if (fnum != (uint16_t)-1) {
    3652           2 :                 cli_nt_delete_on_close(cli, fnum, 0);
    3653           2 :                 cli_close(cli, fnum);
    3654             :         }
    3655           2 :         (void)cli_unlink(cli,
    3656             :                          fname,
    3657             :                          FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3658           2 :         (void)cli_rmdir(cli, dname);
    3659           2 :         return ret;
    3660             : }
    3661             : 
    3662           8 : static NTSTATUS check_empty_fn(struct file_info *finfo,
    3663             :                                 const char *mask,
    3664             :                                 void *private_data)
    3665             : {
    3666           8 :         unsigned int *pcount = (unsigned int *)private_data;
    3667             : 
    3668           8 :         if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
    3669           8 :                 (*pcount)++;
    3670           8 :                 return NT_STATUS_OK;
    3671             :         }
    3672           0 :         return NT_STATUS_DIRECTORY_NOT_EMPTY;
    3673             : }
    3674             : 
    3675             : /*
    3676             :  * Test setting the delete on close bit on a directory
    3677             :  * containing an unwritable file fails or succeeds
    3678             :  * an a share set with "hide unwritable = yes"
    3679             :  * depending on the setting of "delete veto files".
    3680             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
    3681             :  *
    3682             :  * First version. With "delete veto files = yes"
    3683             :  * setting the delete on close should succeed.
    3684             :  */
    3685             : 
    3686           2 : bool run_delete_on_close_nonwrite_delete_yes_test(int dummy)
    3687             : {
    3688           2 :         struct cli_state *cli = NULL;
    3689           0 :         NTSTATUS status;
    3690           2 :         const char *dname = "delete_veto_yes";
    3691           2 :         const char *list_dname = "delete_veto_yes\\*";
    3692           2 :         uint16_t fnum = (uint16_t)-1;
    3693           2 :         bool ret = false;
    3694           2 :         unsigned int list_count = 0;
    3695             : 
    3696           2 :         printf("SMB2 delete on close nonwrite - delete veto yes\n");
    3697             : 
    3698           2 :         if (!torture_init_connection(&cli)) {
    3699           0 :                 return false;
    3700             :         }
    3701             : 
    3702           2 :         status = smbXcli_negprot(cli->conn,
    3703           2 :                                  cli->timeout,
    3704             :                                  PROTOCOL_SMB2_02,
    3705             :                                  PROTOCOL_SMB3_11,
    3706             :                                  NULL,
    3707             :                                  NULL,
    3708             :                                  NULL);
    3709           2 :         if (!NT_STATUS_IS_OK(status)) {
    3710           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3711           0 :                 return false;
    3712             :         }
    3713             : 
    3714           2 :         status = cli_session_setup_creds(cli, torture_creds);
    3715           2 :         if (!NT_STATUS_IS_OK(status)) {
    3716           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3717           0 :                 return false;
    3718             :         }
    3719             : 
    3720           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3721           2 :         if (!NT_STATUS_IS_OK(status)) {
    3722           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3723           0 :                 return false;
    3724             :         }
    3725             : 
    3726             :         /* Ensure target directory is seen as empty. */
    3727           2 :         status = cli_list(cli,
    3728             :                         list_dname,
    3729             :                         FILE_ATTRIBUTE_DIRECTORY |
    3730             :                                 FILE_ATTRIBUTE_HIDDEN |
    3731             :                                 FILE_ATTRIBUTE_SYSTEM,
    3732             :                         check_empty_fn,
    3733             :                         &list_count);
    3734           2 :         if (!NT_STATUS_IS_OK(status)) {
    3735           0 :                 printf("cli_list of %s returned %s\n",
    3736             :                         dname,
    3737             :                         nt_errstr(status));
    3738           0 :                 return false;
    3739             :         }
    3740           2 :         if (list_count != 2) {
    3741           0 :                 printf("cli_list of %s returned a count of %u\n",
    3742             :                         dname,
    3743             :                         list_count);
    3744           0 :                 return false;
    3745             :         }
    3746             : 
    3747             :         /* Open target directory. */
    3748           2 :         status = cli_ntcreate(cli,
    3749             :                                 dname,
    3750             :                                 0,
    3751             :                                 DELETE_ACCESS|FILE_READ_DATA,
    3752             :                                 FILE_ATTRIBUTE_DIRECTORY,
    3753             :                                 FILE_SHARE_READ|
    3754             :                                         FILE_SHARE_WRITE|
    3755             :                                         FILE_SHARE_DELETE,
    3756             :                                 FILE_OPEN,
    3757             :                                 FILE_DIRECTORY_FILE,
    3758             :                                 0,
    3759             :                                 &fnum,
    3760             :                                 NULL);
    3761           2 :         if (!NT_STATUS_IS_OK(status)) {
    3762           0 :                 printf("cli_ntcreate for directory %s returned %s\n",
    3763             :                                 dname,
    3764             :                                 nt_errstr(status));
    3765           0 :                 goto out;
    3766             :         }
    3767             : 
    3768             :         /* Now set the delete on close bit. */
    3769           2 :         status = cli_nt_delete_on_close(cli, fnum, 1);
    3770           2 :         if (!NT_STATUS_IS_OK(status)) {
    3771           0 :                 printf("cli_cli_nt_delete_on_close set for directory "
    3772             :                         "%s returned %s (should have succeeded)\n",
    3773             :                         dname,
    3774             :                         nt_errstr(status));
    3775           0 :                 goto out;
    3776             :         }
    3777             : 
    3778           2 :         ret = true;
    3779             : 
    3780           2 :   out:
    3781             : 
    3782           2 :         if (fnum != (uint16_t)-1) {
    3783           2 :                 (void)cli_nt_delete_on_close(cli, fnum, 0);
    3784           2 :                 (void)cli_close(cli, fnum);
    3785             :         }
    3786           2 :         return ret;
    3787             : }
    3788             : 
    3789             : /*
    3790             :  * Test setting the delete on close bit on a directory
    3791             :  * containing an unwritable file fails or succeeds
    3792             :  * an a share set with "hide unwritable = yes"
    3793             :  * depending on the setting of "delete veto files".
    3794             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
    3795             :  *
    3796             :  * Second version. With "delete veto files = no"
    3797             :  * setting the delete on close should fail.
    3798             :  */
    3799             : 
    3800           2 : bool run_delete_on_close_nonwrite_delete_no_test(int dummy)
    3801             : {
    3802           2 :         struct cli_state *cli = NULL;
    3803           0 :         NTSTATUS status;
    3804           2 :         const char *dname = "delete_veto_no";
    3805           2 :         const char *list_dname = "delete_veto_no\\*";
    3806           2 :         uint16_t fnum = (uint16_t)-1;
    3807           2 :         bool ret = false;
    3808           2 :         unsigned int list_count = 0;
    3809             : 
    3810           2 :         printf("SMB2 delete on close nonwrite - delete veto yes\n");
    3811             : 
    3812           2 :         if (!torture_init_connection(&cli)) {
    3813           0 :                 return false;
    3814             :         }
    3815             : 
    3816           2 :         status = smbXcli_negprot(cli->conn,
    3817           2 :                                  cli->timeout,
    3818             :                                  PROTOCOL_SMB2_02,
    3819             :                                  PROTOCOL_SMB3_11,
    3820             :                                  NULL,
    3821             :                                  NULL,
    3822             :                                  NULL);
    3823           2 :         if (!NT_STATUS_IS_OK(status)) {
    3824           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    3825           0 :                 return false;
    3826             :         }
    3827             : 
    3828           2 :         status = cli_session_setup_creds(cli, torture_creds);
    3829           2 :         if (!NT_STATUS_IS_OK(status)) {
    3830           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    3831           0 :                 return false;
    3832             :         }
    3833             : 
    3834           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    3835           2 :         if (!NT_STATUS_IS_OK(status)) {
    3836           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    3837           0 :                 return false;
    3838             :         }
    3839             : 
    3840             :         /* Ensure target directory is seen as empty. */
    3841           2 :         status = cli_list(cli,
    3842             :                         list_dname,
    3843             :                         FILE_ATTRIBUTE_DIRECTORY |
    3844             :                                 FILE_ATTRIBUTE_HIDDEN |
    3845             :                                 FILE_ATTRIBUTE_SYSTEM,
    3846             :                         check_empty_fn,
    3847             :                         &list_count);
    3848           2 :         if (!NT_STATUS_IS_OK(status)) {
    3849           0 :                 printf("cli_list of %s returned %s\n",
    3850             :                         dname,
    3851             :                         nt_errstr(status));
    3852           0 :                 return false;
    3853             :         }
    3854           2 :         if (list_count != 2) {
    3855           0 :                 printf("cli_list of %s returned a count of %u\n",
    3856             :                         dname,
    3857             :                         list_count);
    3858           0 :                 return false;
    3859             :         }
    3860             : 
    3861             :         /* Open target directory. */
    3862           2 :         status = cli_ntcreate(cli,
    3863             :                                 dname,
    3864             :                                 0,
    3865             :                                 DELETE_ACCESS|FILE_READ_DATA,
    3866             :                                 FILE_ATTRIBUTE_DIRECTORY,
    3867             :                                 FILE_SHARE_READ|
    3868             :                                         FILE_SHARE_WRITE|
    3869             :                                         FILE_SHARE_DELETE,
    3870             :                                 FILE_OPEN,
    3871             :                                 FILE_DIRECTORY_FILE,
    3872             :                                 0,
    3873             :                                 &fnum,
    3874             :                                 NULL);
    3875           2 :         if (!NT_STATUS_IS_OK(status)) {
    3876           0 :                 printf("cli_ntcreate for directory %s returned %s\n",
    3877             :                                 dname,
    3878             :                                 nt_errstr(status));
    3879           0 :                 goto out;
    3880             :         }
    3881             : 
    3882             :         /* Now set the delete on close bit. */
    3883           2 :         status = cli_nt_delete_on_close(cli, fnum, 1);
    3884           2 :         if (NT_STATUS_IS_OK(status)) {
    3885           0 :                 printf("cli_cli_nt_delete_on_close set for directory "
    3886             :                         "%s returned NT_STATUS_OK "
    3887             :                         "(should have failed)\n",
    3888             :                         dname);
    3889           0 :                 goto out;
    3890             :         }
    3891           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
    3892           0 :                 printf("cli_cli_nt_delete_on_close set for directory "
    3893             :                         "%s returned %s "
    3894             :                         "(should have returned "
    3895             :                         "NT_STATUS_DIRECTORY_NOT_EMPTY)\n",
    3896             :                         dname,
    3897             :                         nt_errstr(status));
    3898           0 :                 goto out;
    3899             :         }
    3900             : 
    3901           2 :         ret = true;
    3902             : 
    3903           2 :   out:
    3904             : 
    3905           2 :         if (fnum != (uint16_t)-1) {
    3906           2 :                 (void)cli_nt_delete_on_close(cli, fnum, 0);
    3907           2 :                 (void)cli_close(cli, fnum);
    3908             :         }
    3909           2 :         return ret;
    3910             : }
    3911             : 
    3912             : /*
    3913             :  * Open an SMB2 file readonly and return the inode number.
    3914             :  */
    3915         120 : static NTSTATUS get_smb2_inode(struct cli_state *cli,
    3916             :                                 const char *pathname,
    3917             :                                 uint64_t *ino_ret)
    3918             : {
    3919           0 :         NTSTATUS status;
    3920         120 :         uint64_t fid_persistent = 0;
    3921         120 :         uint64_t fid_volatile = 0;
    3922         120 :         DATA_BLOB outbuf = data_blob_null;
    3923             :         /*
    3924             :          * Open the file.
    3925             :          */
    3926         120 :         status = smb2cli_create(cli->conn,
    3927         120 :                                 cli->timeout,
    3928             :                                 cli->smb2.session,
    3929             :                                 cli->smb2.tcon,
    3930             :                                 pathname,
    3931             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    3932             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    3933             :                                 SEC_STD_SYNCHRONIZE|
    3934             :                                         SEC_FILE_READ_DATA|
    3935             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    3936             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    3937             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    3938             :                                 FILE_OPEN, /* create_disposition, */
    3939             :                                 0, /* create_options, */
    3940             :                                 NULL, /* smb2_create_blobs *blobs */
    3941             :                                 &fid_persistent,
    3942             :                                 &fid_volatile,
    3943             :                                 NULL, /* struct smb_create_returns * */
    3944             :                                 talloc_tos(), /* mem_ctx. */
    3945             :                                 NULL, /* struct smb2_create_blobs * */
    3946             :                                 NULL); /* struct symlink_reparse_struct */
    3947         120 :         if (!NT_STATUS_IS_OK(status)) {
    3948          10 :                 return status;
    3949             :         }
    3950             : 
    3951             :         /*
    3952             :          * Get the inode.
    3953             :          */
    3954         110 :         status = smb2cli_query_info(cli->conn,
    3955         110 :                                     cli->timeout,
    3956             :                                     cli->smb2.session,
    3957             :                                     cli->smb2.tcon,
    3958             :                                     SMB2_0_INFO_FILE,
    3959             :                                     (SMB_FILE_ALL_INFORMATION - 1000), /* in_file_info_class */
    3960             :                                     1024, /* in_max_output_length */
    3961             :                                     NULL, /* in_input_buffer */
    3962             :                                     0, /* in_additional_info */
    3963             :                                     0, /* in_flags */
    3964             :                                     fid_persistent,
    3965             :                                     fid_volatile,
    3966             :                                     talloc_tos(),
    3967             :                                     &outbuf);
    3968             : 
    3969         110 :         if (NT_STATUS_IS_OK(status)) {
    3970         110 :                 *ino_ret = PULL_LE_U64(outbuf.data, 0x40);
    3971             :         }
    3972             : 
    3973         110 :         (void)smb2cli_close(cli->conn,
    3974         110 :                             cli->timeout,
    3975             :                             cli->smb2.session,
    3976             :                             cli->smb2.tcon,
    3977             :                             0,
    3978             :                             fid_persistent,
    3979             :                             fid_volatile);
    3980         110 :         return status;
    3981             : }
    3982             : 
    3983             : /*
    3984             :  * Check an inode matches a given SMB2 path.
    3985             :  */
    3986          98 : static bool smb2_inode_matches(struct cli_state *cli,
    3987             :                                 const char *match_pathname,
    3988             :                                 uint64_t ino_tomatch,
    3989             :                                 const char *test_pathname)
    3990             : {
    3991          98 :         uint64_t test_ino = 0;
    3992           0 :         NTSTATUS status;
    3993             : 
    3994          98 :         status = get_smb2_inode(cli,
    3995             :                                 test_pathname,
    3996             :                                 &test_ino);
    3997          98 :         if (!NT_STATUS_IS_OK(status)) {
    3998           0 :                 printf("%s: Failed to get ino "
    3999             :                         "number for %s, (%s)\n",
    4000             :                         __func__,
    4001             :                         test_pathname,
    4002             :                         nt_errstr(status));
    4003           0 :                 return false;
    4004             :         }
    4005          98 :         if (test_ino != ino_tomatch) {
    4006           0 :                 printf("%s: Inode mismatch, ino_tomatch (%s) "
    4007             :                         "ino=%"PRIu64" test (%s) "
    4008             :                         "ino=%"PRIu64"\n",
    4009             :                         __func__,
    4010             :                         match_pathname,
    4011             :                         ino_tomatch,
    4012             :                         test_pathname,
    4013             :                         test_ino);
    4014           0 :                 return false;
    4015             :         }
    4016          98 :         return true;
    4017             : }
    4018             : 
    4019             : /*
    4020             :  * Delete an SMB2 file on a DFS share.
    4021             :  */
    4022          18 : static NTSTATUS smb2_dfs_delete(struct cli_state *cli,
    4023             :                                 const char *pathname)
    4024             : {
    4025           0 :         NTSTATUS status;
    4026          18 :         uint64_t fid_persistent = 0;
    4027          18 :         uint64_t fid_volatile = 0;
    4028           0 :         uint8_t data[1];
    4029           0 :         DATA_BLOB inbuf;
    4030             : 
    4031             :         /*
    4032             :          * Open the file.
    4033             :          */
    4034          18 :         status = smb2cli_create(cli->conn,
    4035          18 :                                 cli->timeout,
    4036             :                                 cli->smb2.session,
    4037             :                                 cli->smb2.tcon,
    4038             :                                 pathname,
    4039             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4040             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4041             :                                 SEC_STD_SYNCHRONIZE|
    4042             :                                         SEC_STD_DELETE, /* desired_access, */
    4043             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4044             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4045             :                                 FILE_OPEN, /* create_disposition, */
    4046             :                                 0, /* create_options, */
    4047             :                                 NULL, /* smb2_create_blobs *blobs */
    4048             :                                 &fid_persistent,
    4049             :                                 &fid_volatile,
    4050             :                                 NULL, /* struct smb_create_returns * */
    4051             :                                 talloc_tos(), /* mem_ctx. */
    4052             :                                 NULL, /* struct smb2_create_blobs * */
    4053             :                                 NULL); /* struct symlink_reparse_struct */
    4054          18 :         if (!NT_STATUS_IS_OK(status)) {
    4055           8 :                 return status;
    4056             :         }
    4057             : 
    4058             :         /*
    4059             :          * Set delete on close.
    4060             :          */
    4061          10 :         PUSH_LE_U8(&data[0], 0, 1);
    4062          10 :         inbuf.data = &data[0];
    4063          10 :         inbuf.length = 1;
    4064             : 
    4065          10 :         status = smb2cli_set_info(cli->conn,
    4066          10 :                                   cli->timeout,
    4067             :                                   cli->smb2.session,
    4068             :                                   cli->smb2.tcon,
    4069             :                                   SMB2_0_INFO_FILE, /* info_type. */
    4070             :                                   SMB_FILE_DISPOSITION_INFORMATION - 1000, /* info_class */
    4071             :                                   &inbuf,
    4072             :                                   0, /* additional_info. */
    4073             :                                   fid_persistent,
    4074             :                                   fid_volatile);
    4075          10 :         if (!NT_STATUS_IS_OK(status)) {
    4076           0 :                 return status;
    4077             :         }
    4078          10 :         status = smb2cli_close(cli->conn,
    4079          10 :                                cli->timeout,
    4080             :                                cli->smb2.session,
    4081             :                                cli->smb2.tcon,
    4082             :                                0,
    4083             :                                fid_persistent,
    4084             :                                fid_volatile);
    4085          10 :         return status;
    4086             : }
    4087             : 
    4088             : /*
    4089             :  * Rename or hardlink an SMB2 file on a DFS share.
    4090             :  */
    4091           8 : static NTSTATUS smb2_dfs_setinfo_name(struct cli_state *cli,
    4092             :                                       uint64_t fid_persistent,
    4093             :                                       uint64_t fid_volatile,
    4094             :                                       const char *newname,
    4095             :                                       bool do_rename)
    4096             : {
    4097           0 :         NTSTATUS status;
    4098           0 :         DATA_BLOB inbuf;
    4099           8 :         smb_ucs2_t *converted_str = NULL;
    4100           8 :         size_t converted_size_bytes = 0;
    4101           0 :         size_t inbuf_size;
    4102           8 :         uint8_t info_class = 0;
    4103           0 :         bool ok;
    4104             : 
    4105           8 :         ok = push_ucs2_talloc(talloc_tos(),
    4106             :                               &converted_str,
    4107             :                               newname,
    4108             :                               &converted_size_bytes);
    4109           8 :         if (!ok) {
    4110           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4111             :         }
    4112             :         /*
    4113             :          * W2K8 insists the dest name is not null terminated. Remove
    4114             :          * the last 2 zero bytes and reduce the name length.
    4115             :          */
    4116           8 :         if (converted_size_bytes < 2) {
    4117           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4118             :         }
    4119           8 :         converted_size_bytes -= 2;
    4120           8 :         inbuf_size = 20 + converted_size_bytes;
    4121           8 :         if (inbuf_size < 20) {
    4122             :                 /* Integer wrap check. */
    4123           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4124             :         }
    4125             : 
    4126             :         /*
    4127             :          * The Windows 10 SMB2 server has a minimum length
    4128             :          * for a SMB2_FILE_RENAME_INFORMATION buffer of
    4129             :          * 24 bytes. It returns NT_STATUS_INFO_LENGTH_MISMATCH
    4130             :          * if the length is less.
    4131             :          */
    4132           8 :         inbuf_size = MAX(inbuf_size, 24);
    4133           8 :         inbuf = data_blob_talloc_zero(talloc_tos(), inbuf_size);
    4134           8 :         if (inbuf.data == NULL) {
    4135           0 :                 return NT_STATUS_NO_MEMORY;
    4136             :         }
    4137           8 :         PUSH_LE_U32(inbuf.data, 16, converted_size_bytes);
    4138           8 :         memcpy(inbuf.data + 20, converted_str, converted_size_bytes);
    4139           8 :         TALLOC_FREE(converted_str);
    4140             : 
    4141           8 :         if (do_rename == true) {
    4142           4 :                 info_class = SMB_FILE_RENAME_INFORMATION - 1000;
    4143             :         } else {
    4144             :                 /* Hardlink. */
    4145           4 :                 info_class = SMB_FILE_LINK_INFORMATION - 1000;
    4146             :         }
    4147             : 
    4148           8 :         status = smb2cli_set_info(cli->conn,
    4149           8 :                                   cli->timeout,
    4150             :                                   cli->smb2.session,
    4151             :                                   cli->smb2.tcon,
    4152             :                                   SMB2_0_INFO_FILE, /* info_type. */
    4153             :                                   info_class, /* info_class */
    4154             :                                   &inbuf,
    4155             :                                   0, /* additional_info. */
    4156             :                                   fid_persistent,
    4157             :                                   fid_volatile);
    4158           8 :         return status;
    4159             : }
    4160             : 
    4161           4 : static NTSTATUS smb2_dfs_rename(struct cli_state *cli,
    4162             :                                       uint64_t fid_persistent,
    4163             :                                       uint64_t fid_volatile,
    4164             :                                       const char *newname)
    4165             : {
    4166           4 :         return smb2_dfs_setinfo_name(cli,
    4167             :                                      fid_persistent,
    4168             :                                      fid_volatile,
    4169             :                                      newname,
    4170             :                                      true); /* do_rename */
    4171             : }
    4172             : 
    4173           4 : static NTSTATUS smb2_dfs_hlink(struct cli_state *cli,
    4174             :                                uint64_t fid_persistent,
    4175             :                                uint64_t fid_volatile,
    4176             :                                const char *newname)
    4177             : {
    4178           4 :         return smb2_dfs_setinfo_name(cli,
    4179             :                                      fid_persistent,
    4180             :                                      fid_volatile,
    4181             :                                      newname,
    4182             :                                      false); /* do_rename */
    4183             : }
    4184             : 
    4185             : /*
    4186             :  * According to:
    4187             : 
    4188             :  * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/dc9978d7-6299-4c5a-a22d-a039cdc716ea
    4189             :  *
    4190             :  *  (Characters " \ / [ ] : | < > + = ; , * ?,
    4191             :  *  and control characters in range 0x00 through
    4192             :  *  0x1F, inclusive, are illegal in a share name)
    4193             :  *
    4194             :  * But Windows server only checks in DFS sharenames ':'. All other
    4195             :  * share names are allowed.
    4196             :  */
    4197             : 
    4198           2 : static bool test_smb2_dfs_sharenames(struct cli_state *cli,
    4199             :                                      const char *dfs_root_share_name,
    4200             :                                      uint64_t root_ino)
    4201             : {
    4202           0 :         char test_path[9];
    4203           2 :         const char *test_str = "/[]:|<>+=;,*?";
    4204           0 :         const char *p;
    4205           0 :         unsigned int i;
    4206           2 :         bool ino_matched = false;
    4207             : 
    4208             :         /* Setup template pathname. */
    4209           2 :         memcpy(test_path, "SERVER\\X", 9);
    4210             : 
    4211             :         /* Test invalid control characters. */
    4212          64 :         for (i = 1; i < 0x20; i++) {
    4213          62 :                 test_path[7] = i;
    4214          62 :                 ino_matched = smb2_inode_matches(cli,
    4215             :                                          dfs_root_share_name,
    4216             :                                          root_ino,
    4217             :                                          test_path);
    4218          62 :                 if (!ino_matched) {
    4219           0 :                         return false;
    4220             :                 }
    4221             :         }
    4222             : 
    4223             :         /* Test explicit invalid characters. */
    4224          28 :         for (p = test_str; *p != '\0'; p++) {
    4225          26 :                 test_path[7] = *p;
    4226          26 :                 if (*p == ':') {
    4227             :                         /*
    4228             :                          * Only ':' is treated as an INVALID sharename
    4229             :                          * for a DFS SERVER\\SHARE path.
    4230             :                          */
    4231           2 :                         uint64_t test_ino = 0;
    4232           2 :                         NTSTATUS status = get_smb2_inode(cli,
    4233             :                                                          test_path,
    4234             :                                                          &test_ino);
    4235           2 :                         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
    4236           0 :                                 printf("%s:%d Open of %s should get "
    4237             :                                         "NT_STATUS_OBJECT_NAME_INVALID, got %s\n",
    4238             :                                         __FILE__,
    4239             :                                         __LINE__,
    4240             :                                         test_path,
    4241             :                                         nt_errstr(status));
    4242           0 :                                 return false;
    4243             :                         }
    4244             :                 } else {
    4245          24 :                         ino_matched = smb2_inode_matches(cli,
    4246             :                                                  dfs_root_share_name,
    4247             :                                                  root_ino,
    4248             :                                                  test_path);
    4249          24 :                         if (!ino_matched) {
    4250           0 :                                 return false;
    4251             :                         }
    4252             :                 }
    4253             :         }
    4254           2 :         return true;
    4255             : }
    4256             : 
    4257             : /*
    4258             :  * "Raw" test of SMB2 paths to a DFS share.
    4259             :  * We must use the lower level smb2cli_XXXX() interfaces,
    4260             :  * not the cli_XXX() ones here as the ultimate goal is to fix our
    4261             :  * cli_XXX() interfaces to work transparently over DFS.
    4262             :  *
    4263             :  * So here, we're testing the server code, not the client code.
    4264             :  *
    4265             :  * Passes cleanly against Windows.
    4266             :  */
    4267             : 
    4268           2 : bool run_smb2_dfs_paths(int dummy)
    4269             : {
    4270           2 :         struct cli_state *cli = NULL;
    4271           0 :         NTSTATUS status;
    4272           2 :         bool dfs_supported = false;
    4273           2 :         char *dfs_root_share_name = NULL;
    4274           2 :         uint64_t root_ino = 0;
    4275           2 :         uint64_t test_ino = 0;
    4276           2 :         bool ino_matched = false;
    4277           2 :         uint64_t fid_persistent = 0;
    4278           2 :         uint64_t fid_volatile = 0;
    4279           2 :         bool retval = false;
    4280           2 :         bool ok = false;
    4281             : 
    4282           2 :         printf("Starting SMB2-DFS-PATHS\n");
    4283             : 
    4284           2 :         if (!torture_init_connection(&cli)) {
    4285           0 :                 return false;
    4286             :         }
    4287             : 
    4288           2 :         status = smbXcli_negprot(cli->conn,
    4289           2 :                                  cli->timeout,
    4290             :                                  PROTOCOL_SMB2_02,
    4291             :                                  PROTOCOL_SMB3_11,
    4292             :                                  NULL,
    4293             :                                  NULL,
    4294             :                                  NULL);
    4295           2 :         if (!NT_STATUS_IS_OK(status)) {
    4296           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    4297           0 :                 return false;
    4298             :         }
    4299             : 
    4300           2 :         status = cli_session_setup_creds(cli, torture_creds);
    4301           2 :         if (!NT_STATUS_IS_OK(status)) {
    4302           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    4303           0 :                 return false;
    4304             :         }
    4305             : 
    4306           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    4307           2 :         if (!NT_STATUS_IS_OK(status)) {
    4308           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    4309           0 :                 return false;
    4310             :         }
    4311             : 
    4312             :         /* Ensure this is a DFS share. */
    4313           2 :         dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
    4314           2 :         if (!dfs_supported) {
    4315           0 :                 printf("Server %s does not support DFS\n",
    4316           0 :                         smbXcli_conn_remote_name(cli->conn));
    4317           0 :                 return false;
    4318             :         }
    4319           2 :         dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
    4320           2 :         if (!dfs_supported) {
    4321           0 :                 printf("Share %s does not support DFS\n",
    4322           0 :                         cli->share);
    4323           0 :                 return false;
    4324             :         }
    4325             :         /*
    4326             :          * Create the "official" DFS share root name.
    4327             :          * No SMB2 paths can start with '\\'.
    4328             :          */
    4329           2 :         dfs_root_share_name = talloc_asprintf(talloc_tos(),
    4330             :                                         "%s\\%s",
    4331           2 :                                         smbXcli_conn_remote_name(cli->conn),
    4332           2 :                                         cli->share);
    4333           2 :         if (dfs_root_share_name == NULL) {
    4334           0 :                 printf("Out of memory\n");
    4335           0 :                 return false;
    4336             :         }
    4337             : 
    4338             :         /* Get the share root inode number. */
    4339           2 :         status = get_smb2_inode(cli,
    4340             :                                 dfs_root_share_name,
    4341             :                                 &root_ino);
    4342           2 :         if (!NT_STATUS_IS_OK(status)) {
    4343           0 :                 printf("%s:%d Failed to get ino number for share root %s, (%s)\n",
    4344             :                         __FILE__,
    4345             :                         __LINE__,
    4346             :                         dfs_root_share_name,
    4347             :                         nt_errstr(status));
    4348           0 :                 return false;
    4349             :         }
    4350             : 
    4351             :         /*
    4352             :          * Test the Windows algorithm for parsing DFS names.
    4353             :          */
    4354             :         /*
    4355             :          * A single "SERVER" element should open and match the share root.
    4356             :          */
    4357           2 :         ino_matched = smb2_inode_matches(cli,
    4358             :                                          dfs_root_share_name,
    4359             :                                          root_ino,
    4360           2 :                                          smbXcli_conn_remote_name(cli->conn));
    4361           2 :         if (!ino_matched) {
    4362           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    4363             :                         __FILE__,
    4364             :                         __LINE__,
    4365           0 :                         smbXcli_conn_remote_name(cli->conn));
    4366           0 :                 return false;
    4367             :         }
    4368             : 
    4369             :         /*
    4370             :          * An "" DFS empty server name should open and match the share root on
    4371             :          * Windows 2008. Windows 2022 returns NT_STATUS_INVALID_PARAMETER
    4372             :          * for a DFS empty server name.
    4373             :          */
    4374           2 :         status = get_smb2_inode(cli,
    4375             :                                 "",
    4376             :                                 &test_ino);
    4377           2 :         if (NT_STATUS_IS_OK(status)) {
    4378             :                 /*
    4379             :                  * Windows 2008 - open succeeded. Proceed to
    4380             :                  * check ino number.
    4381             :                  */
    4382           0 :                 ino_matched = smb2_inode_matches(cli,
    4383             :                                                  dfs_root_share_name,
    4384             :                                                  root_ino,
    4385             :                                                  "");
    4386           0 :                 if (!ino_matched) {
    4387           0 :                         printf("%s:%d Failed to match ino number for %s\n",
    4388             :                                 __FILE__,
    4389             :                                 __LINE__,
    4390             :                                 "");
    4391           0 :                         return false;
    4392             :                 }
    4393             :         }
    4394           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4395             :                 /*
    4396             :                  * For Windows 2022 we expect to fail with
    4397             :                  * NT_STATUS_INVALID_PARAMETER. Anything else is
    4398             :                  * unexpected.
    4399             :                  */
    4400           0 :                 printf("%s:%d Unexpected error (%s) getting ino number for %s\n",
    4401             :                         __FILE__,
    4402             :                         __LINE__,
    4403             :                         nt_errstr(status),
    4404             :                         "");
    4405           0 :                 return false;
    4406             :         }
    4407             :         /* A "BAD" server name should open and match the share root. */
    4408           2 :         ino_matched = smb2_inode_matches(cli,
    4409             :                                          dfs_root_share_name,
    4410             :                                          root_ino,
    4411             :                                          "BAD");
    4412           2 :         if (!ino_matched) {
    4413           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    4414             :                         __FILE__,
    4415             :                         __LINE__,
    4416             :                         "BAD");
    4417           0 :                 return false;
    4418             :         }
    4419             :         /*
    4420             :          * A "BAD\\BAD" server and share name should open
    4421             :          * and match the share root.
    4422             :          */
    4423           2 :         ino_matched = smb2_inode_matches(cli,
    4424             :                                          dfs_root_share_name,
    4425             :                                          root_ino,
    4426             :                                          "BAD\\BAD");
    4427           2 :         if (!ino_matched) {
    4428           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    4429             :                         __FILE__,
    4430             :                         __LINE__,
    4431             :                         "BAD\\BAD");
    4432           0 :                 return false;
    4433             :         }
    4434             :         /*
    4435             :          * Trying to open "BAD\\BAD\\BAD" should get
    4436             :          * NT_STATUS_OBJECT_NAME_NOT_FOUND.
    4437             :          */
    4438           2 :         status = get_smb2_inode(cli,
    4439             :                                 "BAD\\BAD\\BAD",
    4440             :                                 &test_ino);
    4441           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4442           0 :                 printf("%s:%d Open of %s should get "
    4443             :                         "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
    4444             :                         __FILE__,
    4445             :                         __LINE__,
    4446             :                         "BAD\\BAD\\BAD",
    4447             :                         nt_errstr(status));
    4448           0 :                 return false;
    4449             :         }
    4450             :         /*
    4451             :          * Trying to open "BAD\\BAD\\BAD\\BAD" should get
    4452             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND.
    4453             :          */
    4454           2 :         status = get_smb2_inode(cli,
    4455             :                                 "BAD\\BAD\\BAD\\BAD",
    4456             :                                 &test_ino);
    4457           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    4458           0 :                 printf("%s:%d Open of %s should get "
    4459             :                         "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
    4460             :                         __FILE__,
    4461             :                         __LINE__,
    4462             :                         "BAD\\BAD\\BAD\\BAD",
    4463             :                         nt_errstr(status));
    4464           0 :                 return false;
    4465             :         }
    4466             :         /*
    4467             :          * Test for invalid pathname characters in the servername.
    4468             :          * They are ignored, and it still opens the share root.
    4469             :          */
    4470           2 :         ino_matched = smb2_inode_matches(cli,
    4471             :                                          dfs_root_share_name,
    4472             :                                          root_ino,
    4473             :                                          "::::");
    4474           2 :         if (!ino_matched) {
    4475           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    4476             :                         __FILE__,
    4477             :                         __LINE__,
    4478             :                         "::::");
    4479           0 :                 return false;
    4480             :         }
    4481             : 
    4482             :         /*
    4483             :          * Test for invalid pathname characters in the sharename.
    4484             :          * Invalid sharename characters should still be flagged as
    4485             :          * NT_STATUS_OBJECT_NAME_INVALID. It turns out only ':'
    4486             :          * is considered an invalid sharename character.
    4487             :          */
    4488           2 :         ok = test_smb2_dfs_sharenames(cli,
    4489             :                                       dfs_root_share_name,
    4490             :                                       root_ino);
    4491           2 :         if (!ok) {
    4492           0 :                 return false;
    4493             :         }
    4494             : 
    4495             :         /* Now create a file called "file". */
    4496           2 :         status = smb2cli_create(cli->conn,
    4497           2 :                                 cli->timeout,
    4498           2 :                                 cli->smb2.session,
    4499           2 :                                 cli->smb2.tcon,
    4500             :                                 "BAD\\BAD\\file",
    4501             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4502             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4503             :                                 SEC_STD_SYNCHRONIZE|
    4504             :                                         SEC_STD_DELETE |
    4505             :                                         SEC_FILE_READ_DATA|
    4506             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    4507             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4508             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4509             :                                 FILE_CREATE, /* create_disposition, */
    4510             :                                 0, /* create_options, */
    4511             :                                 NULL, /* smb2_create_blobs *blobs */
    4512             :                                 &fid_persistent,
    4513             :                                 &fid_volatile,
    4514             :                                 NULL, /* struct smb_create_returns * */
    4515             :                                 talloc_tos(), /* mem_ctx. */
    4516             :                                 NULL, /* struct smb2_create_blobs * */
    4517             :                                 NULL); /* struct symlink_reparse_struct */
    4518           2 :         if (!NT_STATUS_IS_OK(status)) {
    4519           0 :                 printf("%s:%d smb2cli_create on %s returned %s\n",
    4520             :                         __FILE__,
    4521             :                         __LINE__,
    4522             :                         "BAD\\BAD\\file",
    4523             :                         nt_errstr(status));
    4524           0 :                 return false;
    4525             :         }
    4526             : 
    4527             :         /*
    4528             :          * Trying to open "BAD\\BAD\\file" should now get
    4529             :          * a valid inode.
    4530             :          */
    4531           2 :         status = get_smb2_inode(cli,
    4532             :                                 "BAD\\BAD\\file",
    4533             :                                 &test_ino);
    4534           2 :         if (!NT_STATUS_IS_OK(status)) {
    4535           0 :                 printf("%s:%d Open of %s should succeed "
    4536             :                         "got %s\n",
    4537             :                         __FILE__,
    4538             :                         __LINE__,
    4539             :                         "BAD\\BAD\\file",
    4540             :                         nt_errstr(status));
    4541           0 :                 goto err;
    4542             :         }
    4543             : 
    4544             :         /*
    4545             :          * Now show that renames use relative,
    4546             :          * not full DFS paths.
    4547             :          */
    4548             : 
    4549             :         /* Full DFS path should fail. */
    4550           2 :         status = smb2_dfs_rename(cli,
    4551             :                                  fid_persistent,
    4552             :                                  fid_volatile,
    4553             :                                  "ANY\\NAME\\renamed_file");
    4554           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    4555           0 :                 printf("%s:%d Rename of %s -> %s should fail "
    4556             :                         "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
    4557             :                         __FILE__,
    4558             :                         __LINE__,
    4559             :                         "BAD\\BAD\\file",
    4560             :                         "ANY\\NAME\\renamed_file",
    4561             :                         nt_errstr(status));
    4562           0 :                 goto err;
    4563             :         }
    4564             :         /* Relative DFS path should succeed. */
    4565           2 :         status = smb2_dfs_rename(cli,
    4566             :                                  fid_persistent,
    4567             :                                  fid_volatile,
    4568             :                                  "renamed_file");
    4569           2 :         if (!NT_STATUS_IS_OK(status)) {
    4570           0 :                 printf("%s:%d: Rename of %s -> %s should succeed. "
    4571             :                         "Got %s\n",
    4572             :                         __FILE__,
    4573             :                         __LINE__,
    4574             :                         "BAD\\BAD\\file",
    4575             :                         "renamed_file",
    4576             :                         nt_errstr(status));
    4577           0 :                 goto err;
    4578             :         }
    4579             : 
    4580             :         /*
    4581             :          * Trying to open "BAD\\BAD\\renamed_file" should now get
    4582             :          * a valid inode.
    4583             :          */
    4584           2 :         status = get_smb2_inode(cli,
    4585             :                                 "BAD\\BAD\\renamed_file",
    4586             :                                 &test_ino);
    4587           2 :         if (!NT_STATUS_IS_OK(status)) {
    4588           0 :                 printf("%s:%d: Open of %s should succeed "
    4589             :                         "got %s\n",
    4590             :                         __FILE__,
    4591             :                         __LINE__,
    4592             :                         "BAD\\BAD\\renamed_file",
    4593             :                         nt_errstr(status));
    4594           0 :                 goto err;
    4595             :         }
    4596             : 
    4597             :         /*
    4598             :          * Now show that hard links use relative,
    4599             :          * not full DFS paths.
    4600             :          */
    4601             : 
    4602             :         /* Full DFS path should fail. */
    4603           2 :         status = smb2_dfs_hlink(cli,
    4604             :                                  fid_persistent,
    4605             :                                  fid_volatile,
    4606             :                                  "ANY\\NAME\\hlink");
    4607           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    4608           0 :                 printf("%s:%d Hlink of %s -> %s should fail "
    4609             :                         "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
    4610             :                         __FILE__,
    4611             :                         __LINE__,
    4612             :                         "ANY\\NAME\\renamed_file",
    4613             :                         "ANY\\NAME\\hlink",
    4614             :                         nt_errstr(status));
    4615           0 :                 goto err;
    4616             :         }
    4617             :         /* Relative DFS path should succeed. */
    4618           2 :         status = smb2_dfs_hlink(cli,
    4619             :                                  fid_persistent,
    4620             :                                  fid_volatile,
    4621             :                                  "hlink");
    4622           2 :         if (!NT_STATUS_IS_OK(status)) {
    4623           0 :                 printf("%s:%d: Hlink of %s -> %s should succeed. "
    4624             :                         "Got %s\n",
    4625             :                         __FILE__,
    4626             :                         __LINE__,
    4627             :                         "ANY\\NAME\\renamed_file",
    4628             :                         "hlink",
    4629             :                         nt_errstr(status));
    4630           0 :                 goto err;
    4631             :         }
    4632             : 
    4633             :         /*
    4634             :          * Trying to open "BAD\\BAD\\hlink" should now get
    4635             :          * a valid inode.
    4636             :          */
    4637           2 :         status = get_smb2_inode(cli,
    4638             :                                 "BAD\\BAD\\hlink",
    4639             :                                 &test_ino);
    4640           2 :         if (!NT_STATUS_IS_OK(status)) {
    4641           0 :                 printf("%s:%d Open of %s should succeed "
    4642             :                         "got %s\n",
    4643             :                         __FILE__,
    4644             :                         __LINE__,
    4645             :                         "BAD\\BAD\\hlink",
    4646             :                         nt_errstr(status));
    4647           0 :                 goto err;
    4648             :         }
    4649             : 
    4650           2 :         retval = true;
    4651             : 
    4652           2 :   err:
    4653             : 
    4654           2 :         if (fid_persistent != 0 || fid_volatile != 0) {
    4655           2 :                 smb2cli_close(cli->conn,
    4656           2 :                               cli->timeout,
    4657           2 :                               cli->smb2.session,
    4658           2 :                               cli->smb2.tcon,
    4659             :                               0, /* flags */
    4660             :                               fid_persistent,
    4661             :                               fid_volatile);
    4662             :         }
    4663             :         /* Delete anything we made. */
    4664           2 :         (void)smb2_dfs_delete(cli, "BAD\\BAD\\BAD");
    4665           2 :         (void)smb2_dfs_delete(cli, "BAD\\BAD\\file");
    4666           2 :         (void)smb2_dfs_delete(cli, "BAD\\BAD\\renamed_file");
    4667           2 :         (void)smb2_dfs_delete(cli, "BAD\\BAD\\hlink");
    4668           2 :         return retval;
    4669             : }
    4670             : 
    4671             : /*
    4672             :  * Add a test that sends DFS paths and sets the
    4673             :  * SMB2 flag FLAGS2_DFS_PATHNAMES, but to a non-DFS
    4674             :  * share. Windows passes this (it just treats the
    4675             :  * pathnames as non-DFS and ignores the FLAGS2_DFS_PATHNAMES
    4676             :  * bit).
    4677             :  */
    4678             : 
    4679           2 : bool run_smb2_non_dfs_share(int dummy)
    4680             : {
    4681           2 :         struct cli_state *cli = NULL;
    4682           0 :         NTSTATUS status;
    4683           2 :         bool dfs_supported = false;
    4684           2 :         uint64_t fid_persistent = 0;
    4685           2 :         uint64_t fid_volatile = 0;
    4686           2 :         bool retval = false;
    4687           2 :         char *dfs_filename = NULL;
    4688             : 
    4689           2 :         printf("Starting SMB2-DFS-NON-DFS-SHARE\n");
    4690             : 
    4691           2 :         if (!torture_init_connection(&cli)) {
    4692           0 :                 return false;
    4693             :         }
    4694             : 
    4695           2 :         status = smbXcli_negprot(cli->conn,
    4696           2 :                                  cli->timeout,
    4697             :                                  PROTOCOL_SMB2_02,
    4698             :                                  PROTOCOL_SMB3_11,
    4699             :                                  NULL,
    4700             :                                  NULL,
    4701             :                                  NULL);
    4702           2 :         if (!NT_STATUS_IS_OK(status)) {
    4703           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    4704           0 :                 return false;
    4705             :         }
    4706             : 
    4707           2 :         status = cli_session_setup_creds(cli, torture_creds);
    4708           2 :         if (!NT_STATUS_IS_OK(status)) {
    4709           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    4710           0 :                 return false;
    4711             :         }
    4712             : 
    4713           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    4714           2 :         if (!NT_STATUS_IS_OK(status)) {
    4715           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    4716           0 :                 return false;
    4717             :         }
    4718             : 
    4719           2 :         dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
    4720           2 :         if (!dfs_supported) {
    4721           0 :                 printf("Server %s does not support DFS\n",
    4722           0 :                         smbXcli_conn_remote_name(cli->conn));
    4723           0 :                 return false;
    4724             :         }
    4725             :         /* Ensure this is *NOT* a DFS share. */
    4726           2 :         dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
    4727           2 :         if (dfs_supported) {
    4728           0 :                 printf("Share %s is a DFS share.\n",
    4729           0 :                         cli->share);
    4730           0 :                 return false;
    4731             :         }
    4732             :         /*
    4733             :          * Force the share to be DFS, as far as the client
    4734             :          * is concerned.
    4735             :          */
    4736           6 :         smb2cli_tcon_set_values(cli->smb2.tcon,
    4737           2 :                                 cli->smb2.session,
    4738           2 :                                 smb2cli_tcon_current_id(cli->smb2.tcon),
    4739             :                                 0,
    4740           2 :                                 smb2cli_tcon_flags(cli->smb2.tcon),
    4741           2 :                                 smb2cli_tcon_capabilities(cli->smb2.tcon) |
    4742             :                                         SMB2_SHARE_CAP_DFS,
    4743             :                                 0);
    4744             : 
    4745             :         /* Come up with a "valid" SMB2 DFS name. */
    4746           2 :         dfs_filename = talloc_asprintf(talloc_tos(),
    4747             :                                        "%s\\%s\\file",
    4748           2 :                                        smbXcli_conn_remote_name(cli->conn),
    4749           2 :                                        cli->share);
    4750           2 :         if (dfs_filename == NULL) {
    4751           0 :                 printf("Out of memory\n");
    4752           0 :                 return false;
    4753             :         }
    4754             : 
    4755             :         /* Now try create dfs_filename. */
    4756           2 :         status = smb2cli_create(cli->conn,
    4757           2 :                                 cli->timeout,
    4758           2 :                                 cli->smb2.session,
    4759           2 :                                 cli->smb2.tcon,
    4760             :                                 dfs_filename,
    4761             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4762             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4763             :                                 SEC_STD_SYNCHRONIZE|
    4764             :                                         SEC_STD_DELETE |
    4765             :                                         SEC_FILE_READ_DATA|
    4766             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    4767             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4768             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4769             :                                 FILE_CREATE, /* create_disposition, */
    4770             :                                 0, /* create_options, */
    4771             :                                 NULL, /* smb2_create_blobs *blobs */
    4772             :                                 &fid_persistent,
    4773             :                                 &fid_volatile,
    4774             :                                 NULL, /* struct smb_create_returns * */
    4775             :                                 talloc_tos(), /* mem_ctx. */
    4776             :                                 NULL, /* struct smb2_create_blobs */
    4777             :                                 NULL); /* struct symlink_reparse_struct */
    4778             :         /*
    4779             :          * Should fail with NT_STATUS_OBJECT_PATH_NOT_FOUND, as
    4780             :          * even though we set the FLAGS2_DFS_PATHNAMES the server
    4781             :          * knows this isn't a DFS share and so treats BAD\\BAD as
    4782             :          * part of the filename.
    4783             :          */
    4784           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    4785           0 :                 printf("%s:%d create of %s should fail "
    4786             :                         "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
    4787             :                         __FILE__,
    4788             :                         __LINE__,
    4789             :                         dfs_filename,
    4790             :                         nt_errstr(status));
    4791           0 :                 goto err;
    4792             :         }
    4793             :         /*
    4794             :          * Prove we can still use non-DFS pathnames, even though
    4795             :          * we are setting the FLAGS2_DFS_PATHNAMES in the SMB2
    4796             :          * request.
    4797             :          */
    4798           2 :         status = smb2cli_create(cli->conn,
    4799           2 :                                 cli->timeout,
    4800           2 :                                 cli->smb2.session,
    4801           2 :                                 cli->smb2.tcon,
    4802             :                                 "file",
    4803             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4804             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4805             :                                 SEC_STD_SYNCHRONIZE|
    4806             :                                         SEC_STD_DELETE |
    4807             :                                         SEC_FILE_READ_DATA|
    4808             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    4809             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4810             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4811             :                                 FILE_CREATE, /* create_disposition, */
    4812             :                                 0, /* create_options, */
    4813             :                                 NULL, /* smb2_create_blobs *blobs */
    4814             :                                 &fid_persistent,
    4815             :                                 &fid_volatile,
    4816             :                                 NULL, /* struct smb_create_returns * */
    4817             :                                 talloc_tos(), /* mem_ctx. */
    4818             :                                 NULL, /* struct smb2_create_blobs * */
    4819             :                                 NULL); /* struct symlink_reparse_struct */
    4820           2 :         if (!NT_STATUS_IS_OK(status)) {
    4821           0 :                 printf("%s:%d smb2cli_create on %s returned %s\n",
    4822             :                         __FILE__,
    4823             :                         __LINE__,
    4824             :                         "file",
    4825             :                         nt_errstr(status));
    4826           0 :                 return false;
    4827             :         }
    4828             : 
    4829           2 :         retval = true;
    4830             : 
    4831           2 :   err:
    4832             : 
    4833           2 :         (void)smb2_dfs_delete(cli, dfs_filename);
    4834           2 :         (void)smb2_dfs_delete(cli, "file");
    4835           2 :         return retval;
    4836             : }
    4837             : 
    4838             : /*
    4839             :  * Add a test that sends a non-DFS path and does not set the
    4840             :  * SMB2 flag FLAGS2_DFS_PATHNAMES to a DFS
    4841             :  * share. Windows passes this (it just treats the
    4842             :  * pathnames as non-DFS).
    4843             :  */
    4844             : 
    4845           2 : bool run_smb2_dfs_share_non_dfs_path(int dummy)
    4846             : {
    4847           2 :         struct cli_state *cli = NULL;
    4848           0 :         NTSTATUS status;
    4849           2 :         bool dfs_supported = false;
    4850           2 :         uint64_t fid_persistent = 0;
    4851           2 :         uint64_t fid_volatile = 0;
    4852           2 :         bool retval = false;
    4853           2 :         char *dfs_filename = NULL;
    4854           2 :         uint64_t root_ino = (uint64_t)-1;
    4855           2 :         bool ino_matched = false;
    4856             : 
    4857           2 :         printf("Starting SMB2-DFS-SHARE-NON-DFS-PATH\n");
    4858             : 
    4859           2 :         if (!torture_init_connection(&cli)) {
    4860           0 :                 return false;
    4861             :         }
    4862             : 
    4863           2 :         status = smbXcli_negprot(cli->conn,
    4864           2 :                                  cli->timeout,
    4865             :                                  PROTOCOL_SMB2_02,
    4866             :                                  PROTOCOL_SMB3_11,
    4867             :                                  NULL,
    4868             :                                  NULL,
    4869             :                                  NULL);
    4870           2 :         if (!NT_STATUS_IS_OK(status)) {
    4871           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    4872           0 :                 return false;
    4873             :         }
    4874             : 
    4875           2 :         status = cli_session_setup_creds(cli, torture_creds);
    4876           2 :         if (!NT_STATUS_IS_OK(status)) {
    4877           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    4878           0 :                 return false;
    4879             :         }
    4880             : 
    4881           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    4882           2 :         if (!NT_STATUS_IS_OK(status)) {
    4883           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    4884           0 :                 return false;
    4885             :         }
    4886             : 
    4887           2 :         dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
    4888           2 :         if (!dfs_supported) {
    4889           0 :                 printf("Server %s does not support DFS\n",
    4890           0 :                         smbXcli_conn_remote_name(cli->conn));
    4891           0 :                 return false;
    4892             :         }
    4893             :         /* Ensure this is a DFS share. */
    4894           2 :         dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
    4895           2 :         if (!dfs_supported) {
    4896           0 :                 printf("Share %s is not a DFS share.\n",
    4897           0 :                         cli->share);
    4898           0 :                 return false;
    4899             :         }
    4900             :         /* Come up with a "valid" SMB2 DFS name. */
    4901           2 :         dfs_filename = talloc_asprintf(talloc_tos(),
    4902             :                                        "%s\\%s\\file",
    4903           2 :                                        smbXcli_conn_remote_name(cli->conn),
    4904           2 :                                        cli->share);
    4905           2 :         if (dfs_filename == NULL) {
    4906           0 :                 printf("Out of memory\n");
    4907           0 :                 return false;
    4908             :         }
    4909             : 
    4910             :         /* Get the root of the share ino. */
    4911           2 :         status = get_smb2_inode(cli,
    4912             :                                 "SERVER\\SHARE",
    4913             :                                 &root_ino);
    4914           2 :         if (!NT_STATUS_IS_OK(status)) {
    4915           0 :                 printf("%s:%d get_smb2_inode on %s returned %s\n",
    4916             :                         __FILE__,
    4917             :                         __LINE__,
    4918             :                         "SERVER\\SHARE",
    4919             :                         nt_errstr(status));
    4920           0 :                 goto err;
    4921             :         }
    4922             : 
    4923             :         /* Create a dfs_filename. */
    4924           2 :         status = smb2cli_create(cli->conn,
    4925           2 :                                 cli->timeout,
    4926           2 :                                 cli->smb2.session,
    4927           2 :                                 cli->smb2.tcon,
    4928             :                                 dfs_filename,
    4929             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4930             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4931             :                                 SEC_STD_SYNCHRONIZE|
    4932             :                                         SEC_STD_DELETE |
    4933             :                                         SEC_FILE_READ_DATA|
    4934             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    4935             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4936             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4937             :                                 FILE_CREATE, /* create_disposition, */
    4938             :                                 0, /* create_options, */
    4939             :                                 NULL, /* smb2_create_blobs *blobs */
    4940             :                                 &fid_persistent,
    4941             :                                 &fid_volatile,
    4942             :                                 NULL, /* struct smb_create_returns * */
    4943             :                                 talloc_tos(), /* mem_ctx. */
    4944             :                                 NULL, /* struct smb2_create_blobs * */
    4945             :                                 NULL); /* psymlink */
    4946           2 :         if (!NT_STATUS_IS_OK(status)) {
    4947           0 :                 printf("%s:%d smb2cli_create on %s returned %s\n",
    4948             :                         __FILE__,
    4949             :                         __LINE__,
    4950             :                         dfs_filename,
    4951             :                         nt_errstr(status));
    4952           0 :                 goto err;
    4953             :         }
    4954             : 
    4955             :         /* Close the handle we just opened. */
    4956           2 :         smb2cli_close(cli->conn,
    4957           2 :                       cli->timeout,
    4958           2 :                       cli->smb2.session,
    4959           2 :                       cli->smb2.tcon,
    4960             :                       0, /* flags */
    4961             :                       fid_persistent,
    4962             :                       fid_volatile);
    4963             : 
    4964           2 :         fid_persistent = 0;
    4965           2 :         fid_volatile = 0;
    4966             : 
    4967             :         /*
    4968             :          * Force the share to be non-DFS, as far as the client
    4969             :          * is concerned.
    4970             :          */
    4971           6 :         smb2cli_tcon_set_values(cli->smb2.tcon,
    4972           2 :                         cli->smb2.session,
    4973           2 :                         smb2cli_tcon_current_id(cli->smb2.tcon),
    4974             :                         0,
    4975           2 :                         smb2cli_tcon_flags(cli->smb2.tcon),
    4976           2 :                         smb2cli_tcon_capabilities(cli->smb2.tcon) &
    4977             :                                 ~SMB2_SHARE_CAP_DFS,
    4978             :                         0);
    4979             : 
    4980             :         /*
    4981             :          * Prove we can still use non-DFS pathnames on a DFS
    4982             :          * share so long as we don't set the FLAGS2_DFS_PATHNAMES
    4983             :          * in the SMB2 request.
    4984             :          */
    4985           2 :         status = smb2cli_create(cli->conn,
    4986           2 :                                 cli->timeout,
    4987           2 :                                 cli->smb2.session,
    4988           2 :                                 cli->smb2.tcon,
    4989             :                                 "file",
    4990             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    4991             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    4992             :                                 SEC_STD_SYNCHRONIZE|
    4993             :                                         SEC_STD_DELETE |
    4994             :                                         SEC_FILE_READ_DATA|
    4995             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    4996             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    4997             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    4998             :                                 FILE_OPEN, /* create_disposition, */
    4999             :                                 0, /* create_options, */
    5000             :                                 NULL, /* smb2_create_blobs *blobs */
    5001             :                                 &fid_persistent,
    5002             :                                 &fid_volatile,
    5003             :                                 NULL, /* struct smb_create_returns * */
    5004             :                                 talloc_tos(), /* mem_ctx. */
    5005             :                                 NULL, /* struct smb2_create_blobs * */
    5006             :                                 NULL); /* psymlink */
    5007           2 :         if (!NT_STATUS_IS_OK(status)) {
    5008           0 :                 printf("%s:%d smb2cli_create on %s returned %s\n",
    5009             :                         __FILE__,
    5010             :                         __LINE__,
    5011             :                         "file",
    5012             :                         nt_errstr(status));
    5013           0 :                 goto err;
    5014             :         }
    5015             : 
    5016             :         /*
    5017             :          * Show that now we're using non-DFS pathnames
    5018             :          * on a DFS share, "" opens the root of the share.
    5019             :          */
    5020           2 :         ino_matched = smb2_inode_matches(cli,
    5021             :                                          "SERVER\\SHARE",
    5022             :                                          root_ino,
    5023             :                                          "");
    5024           2 :         if (!ino_matched) {
    5025           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    5026             :                         __FILE__,
    5027             :                         __LINE__,
    5028             :                         "");
    5029           0 :                 goto err;
    5030             :         }
    5031             : 
    5032           2 :         retval = true;
    5033             : 
    5034           2 :   err:
    5035             : 
    5036           2 :         if (fid_volatile != 0) {
    5037           2 :                 smb2cli_close(cli->conn,
    5038           2 :                               cli->timeout,
    5039           2 :                               cli->smb2.session,
    5040           2 :                               cli->smb2.tcon,
    5041             :                               0, /* flags */
    5042             :                               fid_persistent,
    5043             :                               fid_volatile);
    5044             :         }
    5045           2 :         (void)smb2_dfs_delete(cli, "file");
    5046           2 :         (void)smb2_dfs_delete(cli, dfs_filename);
    5047           2 :         return retval;
    5048             : }
    5049             : 
    5050             : /*
    5051             :  * "Raw" test of an SMB2 filename with one or more leading
    5052             :  * backslash characters to a DFS share.
    5053             :  *
    5054             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
    5055             :  *
    5056             :  * Once the server passes SMB2-DFS-PATHS we can
    5057             :  * fold this test into that one.
    5058             :  *
    5059             :  * Passes cleanly against Windows.
    5060             :  */
    5061             : 
    5062           2 : bool run_smb2_dfs_filename_leading_backslash(int dummy)
    5063             : {
    5064           2 :         struct cli_state *cli = NULL;
    5065           0 :         NTSTATUS status;
    5066           2 :         bool dfs_supported = false;
    5067           2 :         char *dfs_filename_slash = NULL;
    5068           2 :         char *dfs_filename_slash_multi = NULL;
    5069           2 :         uint64_t file_ino = 0;
    5070           2 :         bool ino_matched = false;
    5071           2 :         uint64_t fid_persistent = 0;
    5072           2 :         uint64_t fid_volatile = 0;
    5073           2 :         bool retval = false;
    5074             : 
    5075           2 :         printf("Starting SMB2-DFS-FILENAME-LEADING-BACKSLASH\n");
    5076             : 
    5077           2 :         if (!torture_init_connection(&cli)) {
    5078           0 :                 return false;
    5079             :         }
    5080             : 
    5081           2 :         status = smbXcli_negprot(cli->conn,
    5082           2 :                                  cli->timeout,
    5083             :                                  PROTOCOL_SMB2_02,
    5084             :                                  PROTOCOL_SMB3_11,
    5085             :                                  NULL,
    5086             :                                  NULL,
    5087             :                                  NULL);
    5088           2 :         if (!NT_STATUS_IS_OK(status)) {
    5089           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    5090           0 :                 return false;
    5091             :         }
    5092             : 
    5093           2 :         status = cli_session_setup_creds(cli, torture_creds);
    5094           2 :         if (!NT_STATUS_IS_OK(status)) {
    5095           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    5096           0 :                 return false;
    5097             :         }
    5098             : 
    5099           2 :         status = cli_tree_connect(cli, share, "?????", NULL);
    5100           2 :         if (!NT_STATUS_IS_OK(status)) {
    5101           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    5102           0 :                 return false;
    5103             :         }
    5104             : 
    5105             :         /* Ensure this is a DFS share. */
    5106           2 :         dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
    5107           2 :         if (!dfs_supported) {
    5108           0 :                 printf("Server %s does not support DFS\n",
    5109           0 :                         smbXcli_conn_remote_name(cli->conn));
    5110           0 :                 return false;
    5111             :         }
    5112           2 :         dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
    5113           2 :         if (!dfs_supported) {
    5114           0 :                 printf("Share %s does not support DFS\n",
    5115           0 :                         cli->share);
    5116           0 :                 return false;
    5117             :         }
    5118             : 
    5119             :         /*
    5120             :          * Create the filename with one leading backslash.
    5121             :          */
    5122           2 :         dfs_filename_slash = talloc_asprintf(talloc_tos(),
    5123             :                                         "\\%s\\%s\\file",
    5124           2 :                                         smbXcli_conn_remote_name(cli->conn),
    5125           2 :                                         cli->share);
    5126           2 :         if (dfs_filename_slash == NULL) {
    5127           0 :                 printf("Out of memory\n");
    5128           0 :                 return false;
    5129             :         }
    5130             : 
    5131             :         /*
    5132             :          * Create the filename with many leading backslashes.
    5133             :          */
    5134           2 :         dfs_filename_slash_multi = talloc_asprintf(talloc_tos(),
    5135             :                                         "\\\\\\\\%s\\%s\\file",
    5136           2 :                                         smbXcli_conn_remote_name(cli->conn),
    5137           2 :                                         cli->share);
    5138           2 :         if (dfs_filename_slash_multi == NULL) {
    5139           0 :                 printf("Out of memory\n");
    5140           0 :                 return false;
    5141             :         }
    5142             : 
    5143             :         /*
    5144             :          * Trying to open "\\server\\share\\file" should get
    5145             :          * NT_STATUS_OBJECT_NAME_NOT_FOUND.
    5146             :          */
    5147           2 :         status = get_smb2_inode(cli,
    5148             :                                 dfs_filename_slash,
    5149             :                                 &file_ino);
    5150           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5151           0 :                 printf("%s:%d Open of %s should get "
    5152             :                         "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
    5153             :                         __FILE__,
    5154             :                         __LINE__,
    5155             :                         dfs_filename_slash,
    5156             :                         nt_errstr(status));
    5157           0 :                 return false;
    5158             :         }
    5159             : 
    5160             :         /* Now create a file called "\\server\\share\\file". */
    5161           2 :         status = smb2cli_create(cli->conn,
    5162           2 :                                 cli->timeout,
    5163           2 :                                 cli->smb2.session,
    5164           2 :                                 cli->smb2.tcon,
    5165             :                                 dfs_filename_slash,
    5166             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    5167             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    5168             :                                 SEC_STD_SYNCHRONIZE|
    5169             :                                         SEC_STD_DELETE |
    5170             :                                         SEC_FILE_READ_DATA|
    5171             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    5172             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    5173             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    5174             :                                 FILE_CREATE, /* create_disposition, */
    5175             :                                 0, /* create_options, */
    5176             :                                 NULL, /* smb2_create_blobs *blobs */
    5177             :                                 &fid_persistent,
    5178             :                                 &fid_volatile,
    5179             :                                 NULL, /* struct smb_create_returns * */
    5180             :                                 talloc_tos(), /* mem_ctx. */
    5181             :                                 NULL, /* struct smb2_create_blobs * */
    5182             :                                 NULL); /* struct symlink_reparse_struct */
    5183           2 :         if (!NT_STATUS_IS_OK(status)) {
    5184           0 :                 printf("%s:%d smb2cli_create on %s returned %s\n",
    5185             :                         __FILE__,
    5186             :                         __LINE__,
    5187             :                         dfs_filename_slash,
    5188             :                         nt_errstr(status));
    5189           0 :                 return false;
    5190             :         }
    5191             : 
    5192             :         /*
    5193             :          * Trying to open "\\server\\share\\file" should now get
    5194             :          * a valid inode.
    5195             :          */
    5196           2 :         status = get_smb2_inode(cli,
    5197             :                                 dfs_filename_slash,
    5198             :                                 &file_ino);
    5199           2 :         if (!NT_STATUS_IS_OK(status)) {
    5200           0 :                 printf("%s:%d Open of %s should succeed "
    5201             :                         "got %s\n",
    5202             :                         __FILE__,
    5203             :                         __LINE__,
    5204             :                         dfs_filename_slash,
    5205             :                         nt_errstr(status));
    5206           0 :                 goto err;
    5207             :         }
    5208             : 
    5209             :         /*
    5210             :          * Trying to open "\\\\\\server\\share\\file" should now get
    5211             :          * a valid inode that matches. MacOSX-style of DFS name test.
    5212             :          */
    5213           2 :         ino_matched = smb2_inode_matches(cli,
    5214             :                                 dfs_filename_slash,
    5215             :                                 file_ino,
    5216             :                                 dfs_filename_slash_multi);
    5217           2 :        if (!ino_matched) {
    5218           0 :                 printf("%s:%d Failed to match ino number for %s\n",
    5219             :                         __FILE__,
    5220             :                         __LINE__,
    5221             :                         dfs_filename_slash_multi);
    5222           0 :                 goto err;
    5223             :         }
    5224             : 
    5225           2 :         retval = true;
    5226             : 
    5227           2 :   err:
    5228             : 
    5229           2 :         if (fid_persistent != 0 || fid_volatile != 0) {
    5230           2 :                 smb2cli_close(cli->conn,
    5231           2 :                               cli->timeout,
    5232           2 :                               cli->smb2.session,
    5233           2 :                               cli->smb2.tcon,
    5234             :                               0, /* flags */
    5235             :                               fid_persistent,
    5236             :                               fid_volatile);
    5237             :         }
    5238             :         /* Delete anything we made. */
    5239           2 :         (void)smb2_dfs_delete(cli, dfs_filename_slash);
    5240           2 :         return retval;
    5241             : }
    5242             : 
    5243             : /*
    5244             :  * Ensure a named pipe async read followed by a disconnect
    5245             :  * doesn't crash the server (server crash checked for in
    5246             :  * containing test script:
    5247             :  * source3/script/tests/test_smbtorture_nocrash_s3.sh)
    5248             :  * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
    5249             :  */
    5250             : 
    5251           2 : bool run_smb2_pipe_read_async_disconnect(int dummy)
    5252             : {
    5253           2 :         struct cli_state *cli = NULL;
    5254           0 :         NTSTATUS status;
    5255           2 :         uint64_t fid_persistent = 0;
    5256           2 :         uint64_t fid_volatile = 0;
    5257           0 :         struct tevent_context *ev;
    5258           0 :         struct tevent_req *req;
    5259           2 :         bool retval = false;
    5260             : 
    5261           2 :         printf("Starting SMB2-PIPE-READ-ASYNC-DISCONNECT\n");
    5262             : 
    5263           2 :         if (!torture_init_connection(&cli)) {
    5264           0 :                 return false;
    5265             :         }
    5266             : 
    5267           2 :         status = smbXcli_negprot(cli->conn,
    5268           2 :                                  cli->timeout,
    5269             :                                  PROTOCOL_SMB2_02,
    5270             :                                  PROTOCOL_SMB3_11,
    5271             :                                  NULL,
    5272             :                                  NULL,
    5273             :                                  NULL);
    5274           2 :         if (!NT_STATUS_IS_OK(status)) {
    5275           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    5276           0 :                 return false;
    5277             :         }
    5278             : 
    5279           2 :         status = cli_session_setup_creds(cli, torture_creds);
    5280           2 :         if (!NT_STATUS_IS_OK(status)) {
    5281           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    5282           0 :                 return false;
    5283             :         }
    5284             : 
    5285           2 :         status = cli_tree_connect_creds(cli, "IPC$", "IPC", torture_creds);
    5286           2 :         if (!NT_STATUS_IS_OK(status)) {
    5287           0 :                 printf("cli_tree_connect to IPC$ returned %s\n",
    5288             :                         nt_errstr(status));
    5289           0 :                 return false;
    5290             :         }
    5291             : 
    5292             :         /* Open the SAMR pipe. */
    5293           2 :         status = smb2cli_create(cli->conn,
    5294           2 :                                 cli->timeout,
    5295           2 :                                 cli->smb2.session,
    5296           2 :                                 cli->smb2.tcon,
    5297             :                                 "SAMR",
    5298             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    5299             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    5300             :                                 SEC_STD_SYNCHRONIZE|
    5301             :                                         SEC_FILE_READ_DATA|
    5302             :                                         SEC_FILE_WRITE_DATA, /* desired_access, */
    5303             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    5304             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    5305             :                                 FILE_OPEN, /* create_disposition, */
    5306             :                                 0, /* create_options, */
    5307             :                                 NULL, /* smb2_create_blobs *blobs */
    5308             :                                 &fid_persistent,
    5309             :                                 &fid_volatile,
    5310             :                                 NULL, /* struct smb_create_returns * */
    5311             :                                 talloc_tos(), /* mem_ctx. */
    5312             :                                 NULL, /* struct smb2_create_blobs * */
    5313             :                                 NULL); /* psymlink */
    5314           2 :         if (!NT_STATUS_IS_OK(status)) {
    5315           0 :                 printf("%s:%d smb2cli_create on SAMR returned %s\n",
    5316             :                         __FILE__,
    5317             :                         __LINE__,
    5318             :                         nt_errstr(status));
    5319           0 :                 goto err;
    5320             :         }
    5321             : 
    5322           2 :         ev = samba_tevent_context_init(talloc_tos());
    5323           2 :         if (ev == NULL) {
    5324           0 :                 goto err;
    5325             :         }
    5326             : 
    5327             :         /* Start an async read. */
    5328           2 :         req = smb2cli_read_send(talloc_tos(),
    5329             :                                 ev,
    5330           2 :                                 cli->conn,
    5331           2 :                                 cli->timeout,
    5332           2 :                                 cli->smb2.session,
    5333           2 :                                 cli->smb2.tcon,
    5334             :                                 16*1024,
    5335             :                                 0, /* offset */
    5336             :                                 fid_persistent,
    5337             :                                 fid_volatile,
    5338             :                                 0, /* minimum_count */
    5339             :                                 0); /* remaining_bytes */
    5340           2 :         if (req == NULL) {
    5341           0 :                 goto err;
    5342             :         }
    5343             : 
    5344             :         /* Force disconnect. */
    5345           2 :         smbXcli_conn_disconnect(cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    5346           2 :         fid_volatile = 0;
    5347           2 :         retval = true;
    5348             : 
    5349           2 :   err:
    5350             : 
    5351           2 :         if (fid_volatile != 0) {
    5352           0 :                 smb2cli_close(cli->conn,
    5353           0 :                               cli->timeout,
    5354           0 :                               cli->smb2.session,
    5355           0 :                               cli->smb2.tcon,
    5356             :                               0, /* flags */
    5357             :                               fid_persistent,
    5358             :                               fid_volatile);
    5359             :         }
    5360           2 :         return retval;
    5361             : }
    5362             : 
    5363           2 : bool run_smb2_invalid_pipename(int dummy)
    5364             : {
    5365           2 :         struct cli_state *cli = NULL;
    5366           0 :         NTSTATUS status;
    5367           2 :         uint64_t fid_persistent = 0;
    5368           2 :         uint64_t fid_volatile = 0;
    5369           2 :         const char *unknown_pipe = "badpipe";
    5370           2 :         const char *invalid_pipe = "../../../../../../../../../badpipe";
    5371             : 
    5372           2 :         printf("Starting SMB2-INVALID-PIPENAME\n");
    5373             : 
    5374           2 :         if (!torture_init_connection(&cli)) {
    5375           0 :                 return false;
    5376             :         }
    5377             : 
    5378           2 :         status = smbXcli_negprot(cli->conn,
    5379           2 :                                 cli->timeout,
    5380             :                                 PROTOCOL_SMB2_02,
    5381             :                                 PROTOCOL_SMB3_11,
    5382             :                                 NULL,
    5383             :                                 NULL,
    5384             :                                 NULL);
    5385           2 :         if (!NT_STATUS_IS_OK(status)) {
    5386           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
    5387           0 :                 return false;
    5388             :         }
    5389             : 
    5390           2 :         status = cli_session_setup_creds(cli, torture_creds);
    5391           2 :         if (!NT_STATUS_IS_OK(status)) {
    5392           0 :                 printf("cli_session_setup returned %s\n", nt_errstr(status));
    5393           0 :                 return false;
    5394             :         }
    5395             : 
    5396           2 :         status = cli_tree_connect(cli, "IPC$", "?????", NULL);
    5397           2 :         if (!NT_STATUS_IS_OK(status)) {
    5398           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
    5399           0 :                 return false;
    5400             :         }
    5401             : 
    5402             :         /* Try and connect to an unknown pipename. */
    5403           2 :         status = smb2cli_create(cli->conn,
    5404           2 :                                 cli->timeout,
    5405           2 :                                 cli->smb2.session,
    5406           2 :                                 cli->smb2.tcon,
    5407             :                                 unknown_pipe,
    5408             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    5409             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    5410             :                                 SEC_STD_SYNCHRONIZE|
    5411             :                                         SEC_FILE_READ_DATA|
    5412             :                                         SEC_FILE_WRITE_DATA|
    5413             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    5414             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    5415             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    5416             :                                 FILE_CREATE, /* create_disposition, */
    5417             :                                 0, /* create_options, */
    5418             :                                 NULL, /* smb2_create_blobs *blobs */
    5419             :                                 &fid_persistent,
    5420             :                                 &fid_volatile,
    5421             :                                 NULL, /* struct smb_create_returns * */
    5422             :                                 talloc_tos(), /* mem_ctx. */
    5423             :                                 NULL, /* struct smb2_create_blobs * */
    5424             :                                 NULL); /* struct symlink_reparse_struct */
    5425             :         /* We should get NT_STATUS_OBJECT_NAME_NOT_FOUND */
    5426           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5427           0 :                 printf("%s:%d smb2cli_create on name %s returned %s\n",
    5428             :                         __FILE__,
    5429             :                         __LINE__,
    5430             :                         unknown_pipe,
    5431             :                         nt_errstr(status));
    5432           0 :                 return false;
    5433             :         }
    5434             : 
    5435             :         /* Try and connect to an invalid pipename containing unix separators. */
    5436           2 :         status = smb2cli_create(cli->conn,
    5437           2 :                                 cli->timeout,
    5438           2 :                                 cli->smb2.session,
    5439           2 :                                 cli->smb2.tcon,
    5440             :                                 invalid_pipe,
    5441             :                                 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
    5442             :                                 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
    5443             :                                 SEC_STD_SYNCHRONIZE|
    5444             :                                         SEC_FILE_READ_DATA|
    5445             :                                         SEC_FILE_WRITE_DATA|
    5446             :                                         SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
    5447             :                                 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
    5448             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
    5449             :                                 FILE_CREATE, /* create_disposition, */
    5450             :                                 0, /* create_options, */
    5451             :                                 NULL, /* smb2_create_blobs *blobs */
    5452             :                                 &fid_persistent,
    5453             :                                 &fid_volatile,
    5454             :                                 NULL, /* struct smb_create_returns * */
    5455             :                                 talloc_tos(), /* mem_ctx. */
    5456             :                                 NULL, /* struct smb2_create_blobs * */
    5457             :                                 NULL); /* struct symlink_reparse_struct */
    5458             :         /*
    5459             :          * We should still get NT_STATUS_OBJECT_NAME_NOT_FOUND
    5460             :          * (tested against Windows 2022).
    5461             :          */
    5462           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5463           0 :                 printf("%s:%d smb2cli_create on name %s returned %s\n",
    5464             :                         __FILE__,
    5465             :                         __LINE__,
    5466             :                         invalid_pipe,
    5467             :                         nt_errstr(status));
    5468           0 :                 return false;
    5469             :         }
    5470           2 :         return true;
    5471             : }

Generated by: LCOV version 1.14