LCOV - code coverage report
Current view: top level - source3/torture - test_smb2.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 234 2166 10.8 %
Date: 2024-02-14 10:14:15 Functions: 8 34 23.5 %

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

Generated by: LCOV version 1.14