LCOV - code coverage report
Current view: top level - source3/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 4429 8182 54.1 %
Date: 2024-04-21 15:09:00 Functions: 193 240 80.4 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Andrew Tridgell 1997-1998
       5             :    Copyright (C) Jeremy Allison 2009
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/shmem.h"
      23             : #include "libsmb/namequery.h"
      24             : #include "wbc_async.h"
      25             : #include "torture/proto.h"
      26             : #include "libcli/security/security.h"
      27             : #include "tldap.h"
      28             : #include "tldap_util.h"
      29             : #include "tldap_gensec_bind.h"
      30             : #include "../librpc/gen_ndr/svcctl.h"
      31             : #include "../lib/util/memcache.h"
      32             : #include "nsswitch/winbind_client.h"
      33             : #include "dbwrap/dbwrap.h"
      34             : #include "dbwrap/dbwrap_open.h"
      35             : #include "dbwrap/dbwrap_rbt.h"
      36             : #include "async_smb.h"
      37             : #include "libsmb/libsmb.h"
      38             : #include "libsmb/clirap.h"
      39             : #include "trans2.h"
      40             : #include "libsmb/nmblib.h"
      41             : #include "../lib/util/tevent_ntstatus.h"
      42             : #include "util_tdb.h"
      43             : #include "../libcli/smb/read_smb.h"
      44             : #include "../libcli/smb/smbXcli_base.h"
      45             : #include "lib/util/sys_rw_data.h"
      46             : #include "lib/util/base64.h"
      47             : #include "lib/util/time.h"
      48             : #include "lib/gencache.h"
      49             : #include "lib/util/sys_rw.h"
      50             : #include "lib/util/asn1.h"
      51             : #include "lib/util/util_file.h"
      52             : #include "lib/param/param.h"
      53             : #include "auth/gensec/gensec.h"
      54             : #include "lib/util/string_wrappers.h"
      55             : #include "source3/lib/substitute.h"
      56             : 
      57             : #include <gnutls/gnutls.h>
      58             : #include <gnutls/crypto.h>
      59             : 
      60             : extern char *optarg;
      61             : extern int optind;
      62             : 
      63             : fstring host, workgroup, share, password, username, myname;
      64             : struct cli_credentials *torture_creds;
      65             : static const char *sockops="TCP_NODELAY";
      66             : int torture_nprocs=1;
      67             : static int port_to_use=0;
      68             : int torture_numops=100;
      69             : int torture_blocksize=1024*1024;
      70             : static int procnum; /* records process count number when forking */
      71             : static struct cli_state *current_cli;
      72             : static fstring randomfname;
      73             : static bool use_oplocks;
      74             : static bool use_level_II_oplocks;
      75             : static const char *client_txt = "client_oplocks.txt";
      76             : static bool disable_spnego;
      77             : static bool use_kerberos;
      78             : static bool force_dos_errors;
      79             : static fstring multishare_conn_fname;
      80             : static bool use_multishare_conn = False;
      81             : static bool do_encrypt;
      82             : static const char *local_path = NULL;
      83             : static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
      84             : char *test_filename;
      85             : 
      86             : bool torture_showall = False;
      87             : 
      88             : static double create_procs(bool (*fn)(int), bool *result);
      89             : 
      90             : /********************************************************************
      91             :  Ensure a connection is encrypted.
      92             : ********************************************************************/
      93             : 
      94         200 : static bool force_cli_encryption(struct cli_state *c,
      95             :                         const char *sharename)
      96             : {
      97           0 :         uint16_t major, minor;
      98           0 :         uint32_t caplow, caphigh;
      99           0 :         NTSTATUS status;
     100             : 
     101         200 :         if (!SERVER_HAS_UNIX_CIFS(c)) {
     102           0 :                 d_printf("Encryption required and "
     103             :                         "server that doesn't support "
     104             :                         "UNIX extensions - failing connect\n");
     105           0 :                         return false;
     106             :         }
     107             : 
     108         200 :         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
     109             :                                              &caphigh);
     110         200 :         if (!NT_STATUS_IS_OK(status)) {
     111           0 :                 d_printf("Encryption required and "
     112             :                         "can't get UNIX CIFS extensions "
     113             :                         "version from server: %s\n", nt_errstr(status));
     114           0 :                 return false;
     115             :         }
     116             : 
     117         200 :         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
     118           0 :                 d_printf("Encryption required and "
     119             :                         "share %s doesn't support "
     120             :                         "encryption.\n", sharename);
     121           0 :                 return false;
     122             :         }
     123             : 
     124         200 :         status = cli_smb1_setup_encryption(c, torture_creds);
     125         200 :         if (!NT_STATUS_IS_OK(status)) {
     126           0 :                 d_printf("Encryption required and "
     127             :                         "setup failed with error %s.\n",
     128             :                         nt_errstr(status));
     129           0 :                 return false;
     130             :         }
     131             : 
     132         200 :         return true;
     133             : }
     134             : 
     135             : 
     136         100 : static struct cli_state *open_nbt_connection(void)
     137             : {
     138           0 :         struct cli_state *c;
     139           0 :         NTSTATUS status;
     140         100 :         int flags = 0;
     141             : 
     142         100 :         if (disable_spnego) {
     143           0 :                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
     144             :         }
     145             : 
     146         100 :         if (use_oplocks) {
     147           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     148             :         }
     149             : 
     150         100 :         if (use_level_II_oplocks) {
     151           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     152             :         }
     153             : 
     154         100 :         if (force_dos_errors) {
     155           0 :                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
     156             :         }
     157             : 
     158         100 :         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
     159             :                                 signing_state, flags, &c);
     160         100 :         if (!NT_STATUS_IS_OK(status)) {
     161           0 :                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
     162           0 :                 return NULL;
     163             :         }
     164             : 
     165         100 :         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
     166             : 
     167         100 :         return c;
     168             : }
     169             : 
     170             : /****************************************************************************
     171             :  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
     172             : ****************************************************************************/
     173             : 
     174           4 : static bool cli_bad_session_request(int fd,
     175             :                          struct nmb_name *calling, struct nmb_name *called)
     176             : {
     177           0 :         TALLOC_CTX *frame;
     178           0 :         uint8_t len_buf[4];
     179           0 :         struct iovec iov[3];
     180           0 :         ssize_t len;
     181           0 :         uint8_t *inbuf;
     182           0 :         int err;
     183           4 :         bool ret = false;
     184           0 :         uint8_t message_type;
     185           0 :         uint8_t error;
     186           0 :         struct tevent_context *ev;
     187           0 :         struct tevent_req *req;
     188             : 
     189           4 :         frame = talloc_stackframe();
     190             : 
     191           4 :         iov[0].iov_base = len_buf;
     192           4 :         iov[0].iov_len  = sizeof(len_buf);
     193             : 
     194             :         /* put in the destination name */
     195             : 
     196           4 :         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
     197           4 :                                       called->name_type);
     198           4 :         if (iov[1].iov_base == NULL) {
     199           0 :                 goto fail;
     200             :         }
     201           4 :         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
     202           4 :                                   talloc_get_size(iov[1].iov_base));
     203             : 
     204             :         /* and my name */
     205             : 
     206           4 :         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
     207           4 :                                       calling->name_type);
     208           4 :         if (iov[2].iov_base == NULL) {
     209           0 :                 goto fail;
     210             :         }
     211           4 :         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
     212           4 :                                   talloc_get_size(iov[2].iov_base));
     213             : 
     214             :         /* Deliberately corrupt the name len (first byte) */
     215           4 :         *((uint8_t *)iov[2].iov_base) = 100;
     216             : 
     217             :         /* send a session request (RFC 1002) */
     218             :         /* setup the packet length
     219             :          * Remove four bytes from the length count, since the length
     220             :          * field in the NBT Session Service header counts the number
     221             :          * of bytes which follow.  The cli_send_smb() function knows
     222             :          * about this and accounts for those four bytes.
     223             :          * CRH.
     224             :          */
     225             : 
     226           4 :         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
     227           4 :         SCVAL(len_buf,0,0x81);
     228             : 
     229           4 :         len = write_data_iov(fd, iov, 3);
     230           4 :         if (len == -1) {
     231           0 :                 goto fail;
     232             :         }
     233             : 
     234           4 :         ev = samba_tevent_context_init(frame);
     235           4 :         if (ev == NULL) {
     236           0 :                 goto fail;
     237             :         }
     238           4 :         req = read_smb_send(frame, ev, fd);
     239           4 :         if (req == NULL) {
     240           0 :                 goto fail;
     241             :         }
     242           4 :         if (!tevent_req_poll(req, ev)) {
     243           0 :                 goto fail;
     244             :         }
     245           4 :         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
     246           4 :         if (len == -1) {
     247           0 :                 errno = err;
     248           0 :                 goto fail;
     249             :         }
     250           4 :         TALLOC_FREE(ev);
     251             : 
     252           4 :         message_type = CVAL(inbuf, 0);
     253           4 :         if (message_type != 0x83) {
     254           0 :                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
     255             :                           message_type);
     256           0 :                 goto fail;
     257             :         }
     258             : 
     259           4 :         if (smb_len(inbuf) != 1) {
     260           0 :                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
     261           0 :                           (int)smb_len(inbuf));
     262           0 :                 goto fail;
     263             :         }
     264             : 
     265           4 :         error = CVAL(inbuf, 4);
     266           4 :         if (error !=  0x82) {
     267           0 :                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
     268             :                           (int)error);
     269           0 :                 goto fail;
     270             :         }
     271             : 
     272           4 :         ret = true;
     273           4 : fail:
     274           4 :         TALLOC_FREE(frame);
     275           4 :         return ret;
     276             : }
     277             : 
     278             : /* Insert a NULL at the first separator of the given path and return a pointer
     279             :  * to the remainder of the string.
     280             :  */
     281             : static char *
     282           0 : terminate_path_at_separator(char * path)
     283             : {
     284           0 :         char * p;
     285             : 
     286           0 :         if (!path) {
     287           0 :                 return NULL;
     288             :         }
     289             : 
     290           0 :         if ((p = strchr_m(path, '/'))) {
     291           0 :                 *p = '\0';
     292           0 :                 return p + 1;
     293             :         }
     294             : 
     295           0 :         if ((p = strchr_m(path, '\\'))) {
     296           0 :                 *p = '\0';
     297           0 :                 return p + 1;
     298             :         }
     299             : 
     300             :         /* No separator. */
     301           0 :         return NULL;
     302             : }
     303             : 
     304             : /*
     305             :   parse a //server/share type UNC name
     306             : */
     307           0 : bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     308             :                       char **hostname, char **sharename)
     309             : {
     310           0 :         char *p;
     311             : 
     312           0 :         *hostname = *sharename = NULL;
     313             : 
     314           0 :         if (strncmp(unc_name, "\\\\", 2) &&
     315           0 :             strncmp(unc_name, "//", 2)) {
     316           0 :                 return False;
     317             :         }
     318             : 
     319           0 :         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
     320           0 :         p = terminate_path_at_separator(*hostname);
     321             : 
     322           0 :         if (p && *p) {
     323           0 :                 *sharename = talloc_strdup(mem_ctx, p);
     324           0 :                 terminate_path_at_separator(*sharename);
     325             :         }
     326             : 
     327           0 :         if (*hostname && *sharename) {
     328           0 :                 return True;
     329             :         }
     330             : 
     331           0 :         TALLOC_FREE(*hostname);
     332           0 :         TALLOC_FREE(*sharename);
     333           0 :         return False;
     334             : }
     335             : 
     336         497 : static bool torture_open_connection_share(struct cli_state **c,
     337             :                                    const char *hostname, 
     338             :                                    const char *sharename,
     339             :                                    int flags)
     340             : {
     341           0 :         NTSTATUS status;
     342             : 
     343         497 :         status = cli_full_connection_creds(c,
     344             :                                            myname,
     345             :                                            hostname,
     346             :                                            NULL, /* dest_ss */
     347             :                                            port_to_use,
     348             :                                            sharename,
     349             :                                            "?????",
     350             :                                            torture_creds,
     351             :                                            flags);
     352         497 :         if (!NT_STATUS_IS_OK(status)) {
     353           2 :                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
     354             :                         hostname, sharename, port_to_use, nt_errstr(status));
     355           2 :                 return False;
     356             :         }
     357             : 
     358         495 :         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
     359             : 
     360         495 :         if (do_encrypt) {
     361         198 :                 return force_cli_encryption(*c,
     362             :                                         sharename);
     363             :         }
     364         297 :         return True;
     365             : }
     366             : 
     367         497 : bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
     368             : {
     369         497 :         char **unc_list = NULL;
     370         497 :         int num_unc_names = 0;
     371           0 :         bool result;
     372             : 
     373         497 :         if (use_multishare_conn==True) {
     374           0 :                 char *h, *s;
     375           0 :                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
     376           0 :                 if (!unc_list || num_unc_names <= 0) {
     377           0 :                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
     378           0 :                         exit(1);
     379             :                 }
     380             : 
     381           0 :                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
     382             :                                       NULL, &h, &s)) {
     383           0 :                         printf("Failed to parse UNC name %s\n",
     384           0 :                                unc_list[conn_index % num_unc_names]);
     385           0 :                         TALLOC_FREE(unc_list);
     386           0 :                         exit(1);
     387             :                 }
     388             : 
     389           0 :                 result = torture_open_connection_share(c, h, s, flags);
     390             : 
     391             :                 /* h, s were copied earlier */
     392           0 :                 TALLOC_FREE(unc_list);
     393           0 :                 return result;
     394             :         }
     395             : 
     396         497 :         return torture_open_connection_share(c, host, share, flags);
     397             : }
     398             : 
     399         485 : bool torture_open_connection(struct cli_state **c, int conn_index)
     400             : {
     401         485 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
     402             : 
     403         485 :         if (use_oplocks) {
     404           8 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     405             :         }
     406         485 :         if (use_level_II_oplocks) {
     407           8 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     408             :         }
     409             : 
     410         485 :         return torture_open_connection_flags(c, conn_index, flags);
     411             : }
     412             : 
     413          90 : bool torture_init_connection(struct cli_state **pcli)
     414             : {
     415           0 :         struct cli_state *cli;
     416             : 
     417          90 :         cli = open_nbt_connection();
     418          90 :         if (cli == NULL) {
     419           0 :                 return false;
     420             :         }
     421             : 
     422          90 :         *pcli = cli;
     423          90 :         return true;
     424             : }
     425             : 
     426           5 : bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
     427             : {
     428           5 :         uint16_t old_vuid = cli_state_get_uid(cli);
     429           0 :         NTSTATUS status;
     430           0 :         bool ret;
     431             : 
     432           5 :         cli_state_set_uid(cli, 0);
     433           5 :         status = cli_session_setup_creds(cli, torture_creds);
     434           5 :         ret = NT_STATUS_IS_OK(status);
     435           5 :         *new_vuid = cli_state_get_uid(cli);
     436           5 :         cli_state_set_uid(cli, old_vuid);
     437           5 :         return ret;
     438             : }
     439             : 
     440             : 
     441         421 : bool torture_close_connection(struct cli_state *c)
     442             : {
     443         421 :         bool ret = True;
     444           0 :         NTSTATUS status;
     445             : 
     446         421 :         status = cli_tdis(c);
     447         421 :         if (!NT_STATUS_IS_OK(status)) {
     448           5 :                 printf("tdis failed (%s)\n", nt_errstr(status));
     449           5 :                 ret = False;
     450             :         }
     451             : 
     452         421 :         cli_shutdown(c);
     453             : 
     454         421 :         return ret;
     455             : }
     456             : 
     457          48 : void torture_conn_set_sockopt(struct cli_state *cli)
     458             : {
     459          48 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     460          48 : }
     461             : 
     462          58 : static NTSTATUS torture_delete_fn(struct file_info *finfo,
     463             :                                   const char *pattern,
     464             :                                   void *state)
     465             : {
     466           0 :         NTSTATUS status;
     467          58 :         char *filename = NULL;
     468          58 :         char *dirname = NULL;
     469          58 :         char *p = NULL;
     470          58 :         TALLOC_CTX *frame = talloc_stackframe();
     471          58 :         struct cli_state *cli = (struct cli_state *)state;
     472             : 
     473          58 :         if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
     474          36 :                 TALLOC_FREE(frame);
     475          36 :                 return NT_STATUS_OK;
     476             :         }
     477             : 
     478          22 :         dirname = talloc_strdup(frame, pattern);
     479          22 :         if (dirname == NULL) {
     480           0 :                 TALLOC_FREE(frame);
     481           0 :                 return NT_STATUS_NO_MEMORY;
     482             :         }
     483          22 :         p = strrchr_m(dirname, '\\');
     484          22 :         if (p != NULL) {
     485             :                 /* Remove the terminating '\' */
     486          22 :                 *p = '\0';
     487             :         }
     488          22 :         if (dirname[0] != '\0') {
     489          22 :                 filename = talloc_asprintf(frame,
     490             :                                            "%s\\%s",
     491             :                                            dirname,
     492             :                                            finfo->name);
     493             :         } else {
     494           0 :                 filename = talloc_asprintf(frame,
     495             :                                            "%s",
     496             :                                            finfo->name);
     497             :         }
     498          22 :         if (filename == NULL) {
     499           0 :                 TALLOC_FREE(frame);
     500           0 :                 return NT_STATUS_NO_MEMORY;
     501             :         }
     502          22 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     503           5 :                 char *subdirname = talloc_asprintf(frame,
     504             :                                                    "%s\\*",
     505             :                                                    filename);
     506           5 :                 if (subdirname == NULL) {
     507           0 :                         TALLOC_FREE(frame);
     508           0 :                         return NT_STATUS_NO_MEMORY;
     509             :                 }
     510           5 :                 status = cli_list(cli,
     511             :                                   subdirname,
     512             :                                   FILE_ATTRIBUTE_DIRECTORY |
     513             :                                           FILE_ATTRIBUTE_HIDDEN |
     514             :                                           FILE_ATTRIBUTE_SYSTEM,
     515             :                                   torture_delete_fn,
     516             :                                   cli);
     517           5 :                 if (!NT_STATUS_IS_OK(status)) {
     518           0 :                         printf("torture_delete_fn: cli_list "
     519             :                                 "of %s failed (%s)\n",
     520             :                                 subdirname,
     521             :                                 nt_errstr(status));
     522           0 :                         TALLOC_FREE(frame);
     523           0 :                         return status;
     524             :                 }
     525           5 :                 status = cli_rmdir(cli, filename);
     526             :         } else {
     527          17 :                 status = cli_unlink(cli,
     528             :                                     filename,
     529             :                                     FILE_ATTRIBUTE_SYSTEM |
     530             :                                         FILE_ATTRIBUTE_HIDDEN);
     531             :         }
     532          22 :         if (!NT_STATUS_IS_OK(status)) {
     533           0 :                 if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     534           0 :                         printf("torture_delete_fn: cli_rmdir"
     535             :                                 " of %s failed (%s)\n",
     536             :                                 filename,
     537             :                                 nt_errstr(status));
     538             :                 } else {
     539           0 :                         printf("torture_delete_fn: cli_unlink"
     540             :                                 " of %s failed (%s)\n",
     541             :                                 filename,
     542             :                                 nt_errstr(status));
     543             :                 }
     544             :         }
     545          22 :         TALLOC_FREE(frame);
     546          22 :         return status;
     547             : }
     548             : 
     549          30 : void torture_deltree(struct cli_state *cli, const char *dname)
     550             : {
     551          30 :         char *mask = NULL;
     552           0 :         NTSTATUS status;
     553             : 
     554             :         /* It might be a file */
     555          30 :         (void)cli_unlink(cli,
     556             :                          dname,
     557             :                          FILE_ATTRIBUTE_SYSTEM |
     558             :                                 FILE_ATTRIBUTE_HIDDEN);
     559             : 
     560          30 :         mask = talloc_asprintf(cli,
     561             :                                "%s\\*",
     562             :                                dname);
     563          30 :         if (mask == NULL) {
     564           0 :                 printf("torture_deltree: talloc_asprintf failed\n");
     565           0 :                 return;
     566             :         }
     567             : 
     568          30 :         status = cli_list(cli,
     569             :                         mask,
     570             :                         FILE_ATTRIBUTE_DIRECTORY |
     571             :                                 FILE_ATTRIBUTE_HIDDEN|
     572             :                                 FILE_ATTRIBUTE_SYSTEM,
     573             :                         torture_delete_fn,
     574             :                         cli);
     575          30 :         if (!NT_STATUS_IS_OK(status)) {
     576          17 :                 printf("torture_deltree: cli_list of %s failed (%s)\n",
     577             :                         mask,
     578             :                         nt_errstr(status));
     579             :         }
     580          30 :         TALLOC_FREE(mask);
     581          30 :         status = cli_rmdir(cli, dname);
     582          30 :         if (!NT_STATUS_IS_OK(status)) {
     583          17 :                 printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
     584             :                         dname,
     585             :                         nt_errstr(status));
     586             :         }
     587             : }
     588             : 
     589             : /* check if the server produced the expected dos or nt error code */
     590          53 : static bool check_both_error(int line, NTSTATUS status,
     591             :                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     592             : {
     593          53 :         if (NT_STATUS_IS_DOS(status)) {
     594           0 :                 uint8_t cclass;
     595           0 :                 uint32_t num;
     596             : 
     597             :                 /* Check DOS error */
     598           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     599           0 :                 num = NT_STATUS_DOS_CODE(status);
     600             : 
     601           0 :                 if (eclass != cclass || ecode != num) {
     602           0 :                         printf("unexpected error code class=%d code=%d\n",
     603             :                                (int)cclass, (int)num);
     604           0 :                         printf(" expected %d/%d %s (line=%d)\n",
     605             :                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
     606           0 :                         return false;
     607             :                 }
     608             :         } else {
     609             :                 /* Check NT error */
     610          53 :                 if (!NT_STATUS_EQUAL(nterr, status)) {
     611           0 :                         printf("unexpected error code %s\n",
     612             :                                 nt_errstr(status));
     613           0 :                         printf(" expected %s (line=%d)\n",
     614             :                                 nt_errstr(nterr), line);
     615           0 :                         return false;
     616             :                 }
     617             :         }
     618             : 
     619          53 :         return true;
     620             : }
     621             : 
     622             : 
     623             : /* check if the server produced the expected error code */
     624          38 : static bool check_error(int line, NTSTATUS status,
     625             :                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     626             : {
     627          38 :         if (NT_STATUS_IS_DOS(status)) {
     628           0 :                 uint8_t cclass;
     629           0 :                 uint32_t num;
     630             : 
     631             :                 /* Check DOS error */
     632             : 
     633           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     634           0 :                 num = NT_STATUS_DOS_CODE(status);
     635             : 
     636           0 :                 if (eclass != cclass || ecode != num) {
     637           0 :                         printf("unexpected error code class=%d code=%d\n", 
     638             :                                (int)cclass, (int)num);
     639           0 :                         printf(" expected %d/%d %s (line=%d)\n", 
     640             :                                (int)eclass, (int)ecode, nt_errstr(nterr),
     641             :                                line);
     642           0 :                         return False;
     643             :                 }
     644             : 
     645             :         } else {
     646             :                 /* Check NT error */
     647             : 
     648          38 :                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
     649           1 :                         printf("unexpected error code %s\n",
     650             :                                nt_errstr(status));
     651           1 :                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
     652             :                                line);
     653           1 :                         return False;
     654             :                 }
     655             :         }
     656             : 
     657          37 :         return True;
     658             : }
     659             : 
     660           9 : NTSTATUS cli_qpathinfo1(struct cli_state *cli,
     661             :                         const char *fname,
     662             :                         time_t *change_time,
     663             :                         time_t *access_time,
     664             :                         time_t *write_time,
     665             :                         off_t *size,
     666             :                         uint32_t *pattr)
     667             : {
     668           9 :         int timezone = smb1cli_conn_server_time_zone(cli->conn);
     669           9 :         time_t (*date_fn)(const void *buf, int serverzone) = NULL;
     670           9 :         uint8_t *rdata = NULL;
     671           0 :         uint32_t num_rdata;
     672           0 :         NTSTATUS status;
     673             : 
     674           9 :         status = cli_qpathinfo(talloc_tos(),
     675             :                                cli,
     676             :                                fname,
     677             :                                SMB_INFO_STANDARD,
     678             :                                22,
     679             :                                CLI_BUFFER_SIZE,
     680             :                                &rdata,
     681             :                                &num_rdata);
     682           9 :         if (!NT_STATUS_IS_OK(status)) {
     683           4 :                 return status;
     684             :         }
     685           5 :         if (cli->win95) {
     686           0 :                 date_fn = make_unix_date;
     687             :         } else {
     688           5 :                 date_fn = make_unix_date2;
     689             :         }
     690             : 
     691           5 :         if (change_time) {
     692           5 :                 *change_time = date_fn(rdata + 0, timezone);
     693             :         }
     694           5 :         if (access_time) {
     695           5 :                 *access_time = date_fn(rdata + 4, timezone);
     696             :         }
     697           5 :         if (write_time) {
     698           5 :                 *write_time = date_fn(rdata + 8, timezone);
     699             :         }
     700           5 :         if (size) {
     701           5 :                 *size = PULL_LE_U32(rdata, 12);
     702             :         }
     703           5 :         if (pattr) {
     704           0 :                 *pattr = PULL_LE_U16(rdata, l1_attrFile);
     705             :         }
     706           5 :         return NT_STATUS_OK;
     707             : }
     708             : 
     709           0 : static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
     710             : {
     711           0 :         NTSTATUS status;
     712             : 
     713           0 :         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     714             : 
     715           0 :         while (!NT_STATUS_IS_OK(status)) {
     716           0 :                 if (!check_both_error(__LINE__, status, ERRDOS,
     717           0 :                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
     718           0 :                         return false;
     719             :                 }
     720             : 
     721           0 :                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     722             :         }
     723             : 
     724           0 :         return true;
     725             : }
     726             : 
     727             : 
     728           0 : static bool rw_torture(struct cli_state *c)
     729             : {
     730           0 :         const char *lockfname = "\\torture.lck";
     731           0 :         fstring fname;
     732           0 :         uint16_t fnum;
     733           0 :         uint16_t fnum2;
     734           0 :         pid_t pid2, pid = getpid();
     735           0 :         int i, j;
     736           0 :         char buf[1024];
     737           0 :         bool correct = True;
     738           0 :         size_t nread = 0;
     739           0 :         NTSTATUS status;
     740             : 
     741           0 :         memset(buf, '\0', sizeof(buf));
     742             : 
     743           0 :         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
     744             :                          DENY_NONE, &fnum2);
     745           0 :         if (!NT_STATUS_IS_OK(status)) {
     746           0 :                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
     747             :         }
     748           0 :         if (!NT_STATUS_IS_OK(status)) {
     749           0 :                 printf("open of %s failed (%s)\n",
     750             :                        lockfname, nt_errstr(status));
     751           0 :                 return False;
     752             :         }
     753             : 
     754           0 :         for (i=0;i<torture_numops;i++) {
     755           0 :                 unsigned n = (unsigned)sys_random()%10;
     756             : 
     757           0 :                 if (i % 10 == 0) {
     758           0 :                         printf("%d\r", i); fflush(stdout);
     759             :                 }
     760           0 :                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
     761             : 
     762           0 :                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
     763           0 :                         return False;
     764             :                 }
     765             : 
     766           0 :                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
     767             :                                   DENY_ALL, &fnum);
     768           0 :                 if (!NT_STATUS_IS_OK(status)) {
     769           0 :                         printf("open failed (%s)\n", nt_errstr(status));
     770           0 :                         correct = False;
     771           0 :                         break;
     772             :                 }
     773             : 
     774           0 :                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
     775             :                                       sizeof(pid), NULL);
     776           0 :                 if (!NT_STATUS_IS_OK(status)) {
     777           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     778           0 :                         correct = False;
     779             :                 }
     780             : 
     781           0 :                 for (j=0;j<50;j++) {
     782           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
     783           0 :                                               sizeof(pid)+(j*sizeof(buf)),
     784             :                                               sizeof(buf), NULL);
     785           0 :                         if (!NT_STATUS_IS_OK(status)) {
     786           0 :                                 printf("write failed (%s)\n",
     787             :                                        nt_errstr(status));
     788           0 :                                 correct = False;
     789             :                         }
     790             :                 }
     791             : 
     792           0 :                 pid2 = 0;
     793             : 
     794           0 :                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
     795             :                                   &nread);
     796           0 :                 if (!NT_STATUS_IS_OK(status)) {
     797           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     798           0 :                         correct = false;
     799           0 :                 } else if (nread != sizeof(pid)) {
     800           0 :                         printf("read/write compare failed: "
     801             :                                "recv %ld req %ld\n", (unsigned long)nread,
     802             :                                (unsigned long)sizeof(pid));
     803           0 :                         correct = false;
     804             :                 }
     805             : 
     806           0 :                 if (pid2 != pid) {
     807           0 :                         printf("data corruption!\n");
     808           0 :                         correct = False;
     809             :                 }
     810             : 
     811           0 :                 status = cli_close(c, fnum);
     812           0 :                 if (!NT_STATUS_IS_OK(status)) {
     813           0 :                         printf("close failed (%s)\n", nt_errstr(status));
     814           0 :                         correct = False;
     815             :                 }
     816             : 
     817           0 :                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     818           0 :                 if (!NT_STATUS_IS_OK(status)) {
     819           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
     820           0 :                         correct = False;
     821             :                 }
     822             : 
     823           0 :                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
     824           0 :                 if (!NT_STATUS_IS_OK(status)) {
     825           0 :                         printf("unlock failed (%s)\n", nt_errstr(status));
     826           0 :                         correct = False;
     827             :                 }
     828             :         }
     829             : 
     830           0 :         cli_close(c, fnum2);
     831           0 :         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     832             : 
     833           0 :         printf("%d\n", i);
     834             : 
     835           0 :         return correct;
     836             : }
     837             : 
     838           0 : static bool run_torture(int dummy)
     839             : {
     840           0 :         struct cli_state *cli;
     841           0 :         bool ret;
     842             : 
     843           0 :         cli = current_cli;
     844             : 
     845           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     846             : 
     847           0 :         ret = rw_torture(cli);
     848             : 
     849           0 :         if (!torture_close_connection(cli)) {
     850           0 :                 ret = False;
     851             :         }
     852             : 
     853           0 :         return ret;
     854             : }
     855             : 
     856           0 : static bool rw_torture3(struct cli_state *c, char *lockfname)
     857             : {
     858           0 :         uint16_t fnum = (uint16_t)-1;
     859           0 :         unsigned int i = 0;
     860           0 :         char buf[131072];
     861           0 :         char buf_rd[131072];
     862           0 :         unsigned count;
     863           0 :         unsigned countprev = 0;
     864           0 :         size_t sent = 0;
     865           0 :         bool correct = True;
     866           0 :         NTSTATUS status = NT_STATUS_OK;
     867             : 
     868           0 :         srandom(1);
     869           0 :         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
     870             :         {
     871           0 :                 SIVAL(buf, i, sys_random());
     872             :         }
     873             : 
     874           0 :         if (procnum == 0)
     875             :         {
     876           0 :                 status = cli_unlink(
     877             :                         c, lockfname,
     878             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     879           0 :                 if (!NT_STATUS_IS_OK(status)) {
     880           0 :                         printf("unlink failed (%s) (normal, this file should "
     881             :                                "not exist)\n", nt_errstr(status));
     882             :                 }
     883             : 
     884           0 :                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     885             :                                   DENY_NONE, &fnum);
     886           0 :                 if (!NT_STATUS_IS_OK(status)) {
     887           0 :                         printf("first open read/write of %s failed (%s)\n",
     888             :                                         lockfname, nt_errstr(status));
     889           0 :                         return False;
     890             :                 }
     891             :         }
     892             :         else
     893             :         {
     894           0 :                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
     895             :                 {
     896           0 :                         status = cli_openx(c, lockfname, O_RDONLY, 
     897             :                                          DENY_NONE, &fnum);
     898           0 :                         if (NT_STATUS_IS_OK(status)) {
     899           0 :                                 break;
     900             :                         }
     901           0 :                         smb_msleep(10);
     902             :                 }
     903           0 :                 if (!NT_STATUS_IS_OK(status)) {
     904           0 :                         printf("second open read-only of %s failed (%s)\n",
     905             :                                         lockfname, nt_errstr(status));
     906           0 :                         return False;
     907             :                 }
     908             :         }
     909             : 
     910           0 :         i = 0;
     911           0 :         for (count = 0; count < sizeof(buf); count += sent)
     912             :         {
     913           0 :                 if (count >= countprev) {
     914           0 :                         printf("%d %8d\r", i, count);
     915           0 :                         fflush(stdout);
     916           0 :                         i++;
     917           0 :                         countprev += (sizeof(buf) / 20);
     918             :                 }
     919             : 
     920           0 :                 if (procnum == 0)
     921             :                 {
     922           0 :                         sent = ((unsigned)sys_random()%(20))+ 1;
     923           0 :                         if (sent > sizeof(buf) - count)
     924             :                         {
     925           0 :                                 sent = sizeof(buf) - count;
     926             :                         }
     927             : 
     928           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
     929             :                                               count, sent, NULL);
     930           0 :                         if (!NT_STATUS_IS_OK(status)) {
     931           0 :                                 printf("write failed (%s)\n",
     932             :                                        nt_errstr(status));
     933           0 :                                 correct = False;
     934             :                         }
     935             :                 }
     936             :                 else
     937             :                 {
     938           0 :                         status = cli_read(c, fnum, buf_rd+count, count,
     939             :                                           sizeof(buf)-count, &sent);
     940           0 :                         if(!NT_STATUS_IS_OK(status)) {
     941           0 :                                 printf("read failed offset:%d size:%ld (%s)\n",
     942             :                                        count, (unsigned long)sizeof(buf)-count,
     943             :                                        nt_errstr(status));
     944           0 :                                 correct = False;
     945           0 :                                 sent = 0;
     946           0 :                         } else if (sent > 0) {
     947           0 :                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
     948             :                                 {
     949           0 :                                         printf("read/write compare failed\n");
     950           0 :                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
     951           0 :                                         correct = False;
     952           0 :                                         break;
     953             :                                 }
     954             :                         }
     955             :                 }
     956             : 
     957             :         }
     958             : 
     959           0 :         status = cli_close(c, fnum);
     960           0 :         if (!NT_STATUS_IS_OK(status)) {
     961           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     962           0 :                 correct = False;
     963             :         }
     964             : 
     965           0 :         return correct;
     966             : }
     967             : 
     968          18 : static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     969             : {
     970          18 :         const char *lockfname = "\\torture2.lck";
     971           0 :         uint16_t fnum1;
     972           0 :         uint16_t fnum2;
     973           0 :         int i;
     974           0 :         char buf[131072];
     975           0 :         char buf_rd[131072];
     976          18 :         bool correct = True;
     977           0 :         size_t bytes_read;
     978           0 :         NTSTATUS status;
     979             : 
     980          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     981          18 :         if (!NT_STATUS_IS_OK(status)) {
     982          18 :                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
     983             :         }
     984             : 
     985          18 :         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     986             :                           DENY_NONE, &fnum1);
     987          18 :         if (!NT_STATUS_IS_OK(status)) {
     988           0 :                 printf("first open read/write of %s failed (%s)\n",
     989             :                                 lockfname, nt_errstr(status));
     990           0 :                 return False;
     991             :         }
     992             : 
     993          18 :         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
     994          18 :         if (!NT_STATUS_IS_OK(status)) {
     995           0 :                 printf("second open read-only of %s failed (%s)\n",
     996             :                                 lockfname, nt_errstr(status));
     997           0 :                 cli_close(c1, fnum1);
     998           0 :                 return False;
     999             :         }
    1000             : 
    1001        1818 :         for (i = 0; i < torture_numops; i++)
    1002             :         {
    1003        1800 :                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
    1004        1800 :                 if (i % 10 == 0) {
    1005         180 :                         printf("%d\r", i); fflush(stdout);
    1006             :                 }
    1007             : 
    1008        1800 :                 generate_random_buffer((unsigned char *)buf, buf_size);
    1009             : 
    1010        1800 :                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
    1011             :                                       buf_size, NULL);
    1012        1800 :                 if (!NT_STATUS_IS_OK(status)) {
    1013           0 :                         printf("write failed (%s)\n", nt_errstr(status));
    1014           0 :                         correct = False;
    1015           0 :                         break;
    1016             :                 }
    1017             : 
    1018        1800 :                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
    1019        1800 :                 if(!NT_STATUS_IS_OK(status)) {
    1020           0 :                         printf("read failed (%s)\n", nt_errstr(status));
    1021           0 :                         correct = false;
    1022           0 :                         break;
    1023        1800 :                 } else if (bytes_read != buf_size) {
    1024           0 :                         printf("read failed\n");
    1025           0 :                         printf("read %ld, expected %ld\n",
    1026             :                                (unsigned long)bytes_read,
    1027             :                                (unsigned long)buf_size); 
    1028           0 :                         correct = False;
    1029           0 :                         break;
    1030             :                 }
    1031             : 
    1032        1800 :                 if (memcmp(buf_rd, buf, buf_size) != 0)
    1033             :                 {
    1034           0 :                         printf("read/write compare failed\n");
    1035           0 :                         correct = False;
    1036           0 :                         break;
    1037             :                 }
    1038             :         }
    1039             : 
    1040          18 :         status = cli_close(c2, fnum2);
    1041          18 :         if (!NT_STATUS_IS_OK(status)) {
    1042           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1043           0 :                 correct = False;
    1044             :         }
    1045             : 
    1046          18 :         status = cli_close(c1, fnum1);
    1047          18 :         if (!NT_STATUS_IS_OK(status)) {
    1048           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1049           0 :                 correct = False;
    1050             :         }
    1051             : 
    1052          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1053          18 :         if (!NT_STATUS_IS_OK(status)) {
    1054           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1055           0 :                 correct = False;
    1056             :         }
    1057             : 
    1058          18 :         return correct;
    1059             : }
    1060             : 
    1061           9 : static bool run_readwritetest(int dummy)
    1062             : {
    1063           0 :         struct cli_state *cli1, *cli2;
    1064           9 :         bool test1, test2 = False;
    1065             : 
    1066           9 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1067           0 :                 return False;
    1068             :         }
    1069           9 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1070           9 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1071             : 
    1072           9 :         printf("starting readwritetest\n");
    1073             : 
    1074           9 :         test1 = rw_torture2(cli1, cli2);
    1075           9 :         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
    1076             : 
    1077           9 :         if (test1) {
    1078           9 :                 test2 = rw_torture2(cli1, cli1);
    1079           9 :                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
    1080             :         }
    1081             : 
    1082           9 :         if (!torture_close_connection(cli1)) {
    1083           0 :                 test1 = False;
    1084             :         }
    1085             : 
    1086           9 :         if (!torture_close_connection(cli2)) {
    1087           0 :                 test2 = False;
    1088             :         }
    1089             : 
    1090           9 :         return (test1 && test2);
    1091             : }
    1092             : 
    1093           0 : static bool run_readwritemulti(int dummy)
    1094             : {
    1095           0 :         struct cli_state *cli;
    1096           0 :         bool test;
    1097             : 
    1098           0 :         cli = current_cli;
    1099             : 
    1100           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1101             : 
    1102           0 :         printf("run_readwritemulti: fname %s\n", randomfname);
    1103           0 :         test = rw_torture3(cli, randomfname);
    1104             : 
    1105           0 :         if (!torture_close_connection(cli)) {
    1106           0 :                 test = False;
    1107             :         }
    1108             : 
    1109           0 :         return test;
    1110             : }
    1111             : 
    1112          14 : static bool run_readwritelarge_internal(void)
    1113             : {
    1114           0 :         static struct cli_state *cli1;
    1115           0 :         uint16_t fnum1;
    1116          14 :         const char *lockfname = "\\large.dat";
    1117           0 :         off_t fsize;
    1118           0 :         char buf[126*1024];
    1119          14 :         bool correct = True;
    1120           0 :         NTSTATUS status;
    1121             : 
    1122          14 :         if (!torture_open_connection(&cli1, 0)) {
    1123           0 :                 return False;
    1124             :         }
    1125          14 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1126          14 :         memset(buf,'\0',sizeof(buf));
    1127             : 
    1128          14 :         printf("starting readwritelarge_internal\n");
    1129             : 
    1130          14 :         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1131             : 
    1132          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1133             :                           DENY_NONE, &fnum1);
    1134          14 :         if (!NT_STATUS_IS_OK(status)) {
    1135           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1136           0 :                 return False;
    1137             :         }
    1138             : 
    1139          14 :         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
    1140             : 
    1141          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1142             :                                      NULL, NULL, NULL);
    1143          14 :         if (!NT_STATUS_IS_OK(status)) {
    1144           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1145           0 :                 correct = False;
    1146             :         }
    1147             : 
    1148          14 :         if (fsize == sizeof(buf))
    1149          14 :                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
    1150             :                        (unsigned long)fsize);
    1151             :         else {
    1152           0 :                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
    1153             :                        (unsigned long)fsize);
    1154           0 :                 correct = False;
    1155             :         }
    1156             : 
    1157          14 :         status = cli_close(cli1, fnum1);
    1158          14 :         if (!NT_STATUS_IS_OK(status)) {
    1159           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1160           0 :                 correct = False;
    1161             :         }
    1162             : 
    1163          14 :         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1164          14 :         if (!NT_STATUS_IS_OK(status)) {
    1165           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1166           0 :                 correct = False;
    1167             :         }
    1168             : 
    1169          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1170             :                           DENY_NONE, &fnum1);
    1171          14 :         if (!NT_STATUS_IS_OK(status)) {
    1172           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1173           0 :                 return False;
    1174             :         }
    1175             : 
    1176          14 :         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
    1177             : 
    1178          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1179             :                                      NULL, NULL, NULL);
    1180          14 :         if (!NT_STATUS_IS_OK(status)) {
    1181           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1182           0 :                 correct = False;
    1183             :         }
    1184             : 
    1185          14 :         if (fsize == sizeof(buf))
    1186          14 :                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
    1187             :                        (unsigned long)fsize);
    1188             :         else {
    1189           0 :                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
    1190             :                        (unsigned long)fsize);
    1191           0 :                 correct = False;
    1192             :         }
    1193             : 
    1194          14 :         status = cli_close(cli1, fnum1);
    1195          14 :         if (!NT_STATUS_IS_OK(status)) {
    1196           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1197           0 :                 correct = False;
    1198             :         }
    1199             : 
    1200          14 :         if (!torture_close_connection(cli1)) {
    1201           0 :                 correct = False;
    1202             :         }
    1203          14 :         return correct;
    1204             : }
    1205             : 
    1206           9 : static bool run_readwritelarge(int dummy)
    1207             : {
    1208           9 :         return run_readwritelarge_internal();
    1209             : }
    1210             : 
    1211           5 : static bool run_readwritelarge_signtest(int dummy)
    1212             : {
    1213           0 :         bool ret;
    1214           5 :         signing_state = SMB_SIGNING_REQUIRED;
    1215           5 :         ret = run_readwritelarge_internal();
    1216           5 :         signing_state = SMB_SIGNING_DEFAULT;
    1217           5 :         return ret;
    1218             : }
    1219             : 
    1220             : int line_count = 0;
    1221             : int nbio_id;
    1222             : 
    1223             : #define ival(s) strtol(s, NULL, 0)
    1224             : 
    1225             : /* run a test that simulates an approximate netbench client load */
    1226           0 : static bool run_netbench(int client)
    1227             : {
    1228           0 :         struct cli_state *cli;
    1229           0 :         int i;
    1230           0 :         char line[1024];
    1231           0 :         char cname[20];
    1232           0 :         FILE *f;
    1233           0 :         const char *params[20];
    1234           0 :         bool correct = True;
    1235             : 
    1236           0 :         cli = current_cli;
    1237             : 
    1238           0 :         nbio_id = client;
    1239             : 
    1240           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1241             : 
    1242           0 :         nb_setup(cli);
    1243             : 
    1244           0 :         slprintf(cname,sizeof(cname)-1, "client%d", client);
    1245             : 
    1246           0 :         f = fopen(client_txt, "r");
    1247             : 
    1248           0 :         if (!f) {
    1249           0 :                 perror(client_txt);
    1250           0 :                 return False;
    1251             :         }
    1252             : 
    1253           0 :         while (fgets(line, sizeof(line)-1, f)) {
    1254           0 :                 char *saveptr;
    1255           0 :                 line_count++;
    1256             : 
    1257           0 :                 line[strlen(line)-1] = 0;
    1258             : 
    1259             :                 /* printf("[%d] %s\n", line_count, line); */
    1260             : 
    1261           0 :                 all_string_sub(line,"client1", cname, sizeof(line));
    1262             : 
    1263             :                 /* parse the command parameters */
    1264           0 :                 params[0] = strtok_r(line, " ", &saveptr);
    1265           0 :                 i = 0;
    1266           0 :                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
    1267             : 
    1268           0 :                 params[i] = "";
    1269             : 
    1270           0 :                 if (i < 2) continue;
    1271             : 
    1272           0 :                 if (!strncmp(params[0],"SMB", 3)) {
    1273           0 :                         printf("ERROR: You are using a dbench 1 load file\n");
    1274           0 :                         exit(1);
    1275             :                 }
    1276             : 
    1277           0 :                 if (!strcmp(params[0],"NTCreateX")) {
    1278           0 :                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
    1279           0 :                                    ival(params[4]));
    1280           0 :                 } else if (!strcmp(params[0],"Close")) {
    1281           0 :                         nb_close(ival(params[1]));
    1282           0 :                 } else if (!strcmp(params[0],"Rename")) {
    1283           0 :                         nb_rename(params[1], params[2]);
    1284           0 :                 } else if (!strcmp(params[0],"Unlink")) {
    1285           0 :                         nb_unlink(params[1]);
    1286           0 :                 } else if (!strcmp(params[0],"Deltree")) {
    1287           0 :                         nb_deltree(params[1]);
    1288           0 :                 } else if (!strcmp(params[0],"Rmdir")) {
    1289           0 :                         nb_rmdir(params[1]);
    1290           0 :                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
    1291           0 :                         nb_qpathinfo(params[1]);
    1292           0 :                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
    1293           0 :                         nb_qfileinfo(ival(params[1]));
    1294           0 :                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
    1295           0 :                         nb_qfsinfo(ival(params[1]));
    1296           0 :                 } else if (!strcmp(params[0],"FIND_FIRST")) {
    1297           0 :                         nb_findfirst(params[1]);
    1298           0 :                 } else if (!strcmp(params[0],"WriteX")) {
    1299           0 :                         nb_writex(ival(params[1]), 
    1300           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1301           0 :                 } else if (!strcmp(params[0],"ReadX")) {
    1302           0 :                         nb_readx(ival(params[1]), 
    1303           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1304           0 :                 } else if (!strcmp(params[0],"Flush")) {
    1305           0 :                         nb_flush(ival(params[1]));
    1306             :                 } else {
    1307           0 :                         printf("Unknown operation %s\n", params[0]);
    1308           0 :                         exit(1);
    1309             :                 }
    1310             :         }
    1311           0 :         fclose(f);
    1312             : 
    1313           0 :         nb_cleanup();
    1314             : 
    1315           0 :         if (!torture_close_connection(cli)) {
    1316           0 :                 correct = False;
    1317             :         }
    1318             : 
    1319           0 :         return correct;
    1320             : }
    1321             : 
    1322             : 
    1323             : /* run a test that simulates an approximate netbench client load */
    1324           0 : static bool run_nbench(int dummy)
    1325             : {
    1326           0 :         double t;
    1327           0 :         bool correct = True;
    1328             : 
    1329           0 :         nbio_shmem(torture_nprocs);
    1330             : 
    1331           0 :         nbio_id = -1;
    1332             : 
    1333           0 :         signal(SIGALRM, nb_alarm);
    1334           0 :         alarm(1);
    1335           0 :         t = create_procs(run_netbench, &correct);
    1336           0 :         alarm(0);
    1337             : 
    1338           0 :         printf("\nThroughput %g MB/sec\n", 
    1339           0 :                1.0e-6 * nbio_total() / t);
    1340           0 :         return correct;
    1341             : }
    1342             : 
    1343             : 
    1344             : /*
    1345             :   This test checks for two things:
    1346             : 
    1347             :   1) correct support for retaining locks over a close (ie. the server
    1348             :      must not use posix semantics)
    1349             :   2) support for lock timeouts
    1350             :  */
    1351           5 : static bool run_locktest1(int dummy)
    1352             : {
    1353           0 :         struct cli_state *cli1, *cli2;
    1354           5 :         const char *fname = "\\lockt1.lck";
    1355           0 :         uint16_t fnum1, fnum2, fnum3;
    1356           0 :         time_t t1, t2;
    1357           0 :         unsigned lock_timeout;
    1358           0 :         NTSTATUS status;
    1359             : 
    1360           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1361           0 :                 return False;
    1362             :         }
    1363           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1364           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1365             : 
    1366           5 :         printf("starting locktest1\n");
    1367             : 
    1368           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1369             : 
    1370           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1371             :                           &fnum1);
    1372           5 :         if (!NT_STATUS_IS_OK(status)) {
    1373           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1374           0 :                 return False;
    1375             :         }
    1376             : 
    1377           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
    1378           5 :         if (!NT_STATUS_IS_OK(status)) {
    1379           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1380           0 :                 return False;
    1381             :         }
    1382             : 
    1383           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
    1384           5 :         if (!NT_STATUS_IS_OK(status)) {
    1385           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1386           0 :                 return False;
    1387             :         }
    1388             : 
    1389           5 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    1390           5 :         if (!NT_STATUS_IS_OK(status)) {
    1391           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1392           0 :                 return false;
    1393             :         }
    1394             : 
    1395           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1396           5 :         if (NT_STATUS_IS_OK(status)) {
    1397           0 :                 printf("lock2 succeeded! This is a locking bug\n");
    1398           0 :                 return false;
    1399             :         } else {
    1400           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1401           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1402           0 :                         return false;
    1403             :                 }
    1404             :         }
    1405             : 
    1406           5 :         lock_timeout = (1 + (random() % 20));
    1407           5 :         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
    1408           5 :         t1 = time(NULL);
    1409           5 :         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
    1410           5 :         if (NT_STATUS_IS_OK(status)) {
    1411           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1412           0 :                 return false;
    1413             :         } else {
    1414           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1415           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1416           0 :                         return false;
    1417             :                 }
    1418             :         }
    1419           5 :         t2 = time(NULL);
    1420             : 
    1421           5 :         if (ABS(t2 - t1) < lock_timeout-1) {
    1422           0 :                 printf("error: This server appears not to support timed lock requests\n");
    1423             :         }
    1424             : 
    1425           5 :         printf("server slept for %u seconds for a %u second timeout\n",
    1426             :                (unsigned int)(t2-t1), lock_timeout);
    1427             : 
    1428           5 :         status = cli_close(cli1, fnum2);
    1429           5 :         if (!NT_STATUS_IS_OK(status)) {
    1430           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1431           0 :                 return False;
    1432             :         }
    1433             : 
    1434           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1435           5 :         if (NT_STATUS_IS_OK(status)) {
    1436           0 :                 printf("lock4 succeeded! This is a locking bug\n");
    1437           0 :                 return false;
    1438             :         } else {
    1439           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1440           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1441           0 :                         return false;
    1442             :                 }
    1443             :         }
    1444             : 
    1445           5 :         status = cli_close(cli1, fnum1);
    1446           5 :         if (!NT_STATUS_IS_OK(status)) {
    1447           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1448           0 :                 return False;
    1449             :         }
    1450             : 
    1451           5 :         status = cli_close(cli2, fnum3);
    1452           5 :         if (!NT_STATUS_IS_OK(status)) {
    1453           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1454           0 :                 return False;
    1455             :         }
    1456             : 
    1457           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1458           5 :         if (!NT_STATUS_IS_OK(status)) {
    1459           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1460           0 :                 return False;
    1461             :         }
    1462             : 
    1463             : 
    1464           5 :         if (!torture_close_connection(cli1)) {
    1465           0 :                 return False;
    1466             :         }
    1467             : 
    1468           5 :         if (!torture_close_connection(cli2)) {
    1469           0 :                 return False;
    1470             :         }
    1471             : 
    1472           5 :         printf("Passed locktest1\n");
    1473           5 :         return True;
    1474             : }
    1475             : 
    1476             : /*
    1477             :   this checks to see if a secondary tconx can use open files from an
    1478             :   earlier tconx
    1479             :  */
    1480           5 : static bool run_tcon_test(int dummy)
    1481             : {
    1482           0 :         static struct cli_state *cli;
    1483           5 :         const char *fname = "\\tcontest.tmp";
    1484           0 :         uint16_t fnum1;
    1485           0 :         uint32_t cnum1, cnum2, cnum3;
    1486           5 :         struct smbXcli_tcon *orig_tcon = NULL;
    1487           5 :         char *orig_share = NULL;
    1488           0 :         uint16_t vuid1, vuid2;
    1489           0 :         char buf[4];
    1490           5 :         bool ret = True;
    1491           0 :         NTSTATUS status;
    1492             : 
    1493           5 :         memset(buf, '\0', sizeof(buf));
    1494             : 
    1495           5 :         if (!torture_open_connection(&cli, 0)) {
    1496           0 :                 return False;
    1497             :         }
    1498           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1499             : 
    1500           5 :         printf("starting tcontest\n");
    1501             : 
    1502           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1503             : 
    1504           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1505           5 :         if (!NT_STATUS_IS_OK(status)) {
    1506           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1507           0 :                 return False;
    1508             :         }
    1509             : 
    1510           5 :         cnum1 = cli_state_get_tid(cli);
    1511           5 :         vuid1 = cli_state_get_uid(cli);
    1512             : 
    1513           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1514           5 :         if (!NT_STATUS_IS_OK(status)) {
    1515           0 :                 printf("initial write failed (%s)", nt_errstr(status));
    1516           0 :                 return False;
    1517             :         }
    1518             : 
    1519           5 :         cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
    1520             : 
    1521           5 :         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
    1522           5 :         if (!NT_STATUS_IS_OK(status)) {
    1523           0 :                 printf("%s refused 2nd tree connect (%s)\n", host,
    1524             :                        nt_errstr(status));
    1525           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1526           0 :                 cli_shutdown(cli);
    1527           0 :                 return False;
    1528             :         }
    1529             : 
    1530           5 :         cnum2 = cli_state_get_tid(cli);
    1531           5 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
    1532           5 :         vuid2 = cli_state_get_uid(cli) + 1;
    1533             : 
    1534             :         /* try a write with the wrong tid */
    1535           5 :         cli_state_set_tid(cli, cnum2);
    1536             : 
    1537           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1538           5 :         if (NT_STATUS_IS_OK(status)) {
    1539           0 :                 printf("* server allows write with wrong TID\n");
    1540           0 :                 ret = False;
    1541             :         } else {
    1542           5 :                 printf("server fails write with wrong TID : %s\n",
    1543             :                        nt_errstr(status));
    1544             :         }
    1545             : 
    1546             : 
    1547             :         /* try a write with an invalid tid */
    1548           5 :         cli_state_set_tid(cli, cnum3);
    1549             : 
    1550           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1551           5 :         if (NT_STATUS_IS_OK(status)) {
    1552           0 :                 printf("* server allows write with invalid TID\n");
    1553           0 :                 ret = False;
    1554             :         } else {
    1555           5 :                 printf("server fails write with invalid TID : %s\n",
    1556             :                        nt_errstr(status));
    1557             :         }
    1558             : 
    1559             :         /* try a write with an invalid vuid */
    1560           5 :         cli_state_set_uid(cli, vuid2);
    1561           5 :         cli_state_set_tid(cli, cnum1);
    1562             : 
    1563           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1564           5 :         if (NT_STATUS_IS_OK(status)) {
    1565           0 :                 printf("* server allows write with invalid VUID\n");
    1566           0 :                 ret = False;
    1567             :         } else {
    1568           5 :                 printf("server fails write with invalid VUID : %s\n",
    1569             :                        nt_errstr(status));
    1570             :         }
    1571             : 
    1572           5 :         cli_state_set_tid(cli, cnum1);
    1573           5 :         cli_state_set_uid(cli, vuid1);
    1574             : 
    1575           5 :         status = cli_close(cli, fnum1);
    1576           5 :         if (!NT_STATUS_IS_OK(status)) {
    1577           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1578           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1579           0 :                 cli_shutdown(cli);
    1580           0 :                 return False;
    1581             :         }
    1582             : 
    1583           5 :         cli_state_set_tid(cli, cnum2);
    1584             : 
    1585           5 :         status = cli_tdis(cli);
    1586           5 :         if (!NT_STATUS_IS_OK(status)) {
    1587           0 :                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
    1588           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1589           0 :                 cli_shutdown(cli);
    1590           0 :                 return False;
    1591             :         }
    1592             : 
    1593           5 :         cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1594             : 
    1595           5 :         cli_state_set_tid(cli, cnum1);
    1596             : 
    1597           5 :         if (!torture_close_connection(cli)) {
    1598           0 :                 return False;
    1599             :         }
    1600             : 
    1601           5 :         return ret;
    1602             : }
    1603             : 
    1604             : 
    1605             : /*
    1606             :  checks for old style tcon support
    1607             :  */
    1608           5 : static bool run_tcon2_test(int dummy)
    1609             : {
    1610           0 :         static struct cli_state *cli;
    1611           0 :         uint16_t cnum, max_xmit;
    1612           0 :         char *service;
    1613           0 :         NTSTATUS status;
    1614             : 
    1615           5 :         if (!torture_open_connection(&cli, 0)) {
    1616           0 :                 return False;
    1617             :         }
    1618           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1619             : 
    1620           5 :         printf("starting tcon2 test\n");
    1621             : 
    1622           5 :         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
    1623           0 :                 return false;
    1624             :         }
    1625             : 
    1626           5 :         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
    1627             : 
    1628           5 :         SAFE_FREE(service);
    1629             : 
    1630           5 :         if (!NT_STATUS_IS_OK(status)) {
    1631           5 :                 printf("tcon2 failed : %s\n", nt_errstr(status));
    1632             :         } else {
    1633           0 :                 printf("tcon OK : max_xmit=%d cnum=%d\n",
    1634             :                        (int)max_xmit, (int)cnum);
    1635             :         }
    1636             : 
    1637           5 :         if (!torture_close_connection(cli)) {
    1638           0 :                 return False;
    1639             :         }
    1640             : 
    1641           5 :         printf("Passed tcon2 test\n");
    1642           5 :         return True;
    1643             : }
    1644             : 
    1645          50 : static bool tcon_devtest(struct cli_state *cli,
    1646             :                          const char *myshare, const char *devtype,
    1647             :                          const char *return_devtype,
    1648             :                          NTSTATUS expected_error)
    1649             : {
    1650           0 :         NTSTATUS status;
    1651           0 :         bool ret;
    1652             : 
    1653          50 :         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
    1654             : 
    1655          50 :         if (NT_STATUS_IS_OK(expected_error)) {
    1656          20 :                 if (NT_STATUS_IS_OK(status)) {
    1657          40 :                         if (return_devtype != NULL &&
    1658          20 :                             strequal(cli->dev, return_devtype)) {
    1659          20 :                                 ret = True;
    1660             :                         } else { 
    1661           0 :                                 printf("tconX to share %s with type %s "
    1662             :                                        "succeeded but returned the wrong "
    1663             :                                        "device type (got [%s] but should have got [%s])\n",
    1664             :                                        myshare, devtype, cli->dev, return_devtype);
    1665           0 :                                 ret = False;
    1666             :                         }
    1667             :                 } else {
    1668           0 :                         printf("tconX to share %s with type %s "
    1669             :                                "should have succeeded but failed\n",
    1670             :                                myshare, devtype);
    1671           0 :                         ret = False;
    1672             :                 }
    1673          20 :                 cli_tdis(cli);
    1674             :         } else {
    1675          30 :                 if (NT_STATUS_IS_OK(status)) {
    1676           0 :                         printf("tconx to share %s with type %s "
    1677             :                                "should have failed but succeeded\n",
    1678             :                                myshare, devtype);
    1679           0 :                         ret = False;
    1680             :                 } else {
    1681          30 :                         if (NT_STATUS_EQUAL(status, expected_error)) {
    1682          30 :                                 ret = True;
    1683             :                         } else {
    1684           0 :                                 printf("Returned unexpected error\n");
    1685           0 :                                 ret = False;
    1686             :                         }
    1687             :                 }
    1688             :         }
    1689          50 :         return ret;
    1690             : }
    1691             : 
    1692             : /*
    1693             :  checks for correct tconX support
    1694             :  */
    1695           5 : static bool run_tcon_devtype_test(int dummy)
    1696             : {
    1697           0 :         static struct cli_state *cli1 = NULL;
    1698           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
    1699           0 :         NTSTATUS status;
    1700           5 :         bool ret = True;
    1701             : 
    1702           5 :         status = cli_full_connection_creds(&cli1,
    1703             :                                            myname,
    1704             :                                            host,
    1705             :                                            NULL, /* dest_ss */
    1706             :                                            port_to_use,
    1707             :                                            NULL, /* service */
    1708             :                                            NULL, /* service_type */
    1709             :                                            torture_creds,
    1710             :                                            flags);
    1711             : 
    1712           5 :         if (!NT_STATUS_IS_OK(status)) {
    1713           0 :                 printf("could not open connection\n");
    1714           0 :                 return False;
    1715             :         }
    1716             : 
    1717           5 :         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1718           0 :                 ret = False;
    1719             : 
    1720           5 :         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
    1721           0 :                 ret = False;
    1722             : 
    1723           5 :         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1724           0 :                 ret = False;
    1725             : 
    1726           5 :         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
    1727           0 :                 ret = False;
    1728             : 
    1729           5 :         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1730           0 :                 ret = False;
    1731             : 
    1732           5 :         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
    1733           0 :                 ret = False;
    1734             : 
    1735           5 :         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
    1736           0 :                 ret = False;
    1737             : 
    1738           5 :         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1739           0 :                 ret = False;
    1740             : 
    1741           5 :         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1742           0 :                 ret = False;
    1743             : 
    1744           5 :         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1745           0 :                 ret = False;
    1746             : 
    1747           5 :         cli_shutdown(cli1);
    1748             : 
    1749           5 :         if (ret)
    1750           5 :                 printf("Passed tcondevtest\n");
    1751             : 
    1752           5 :         return ret;
    1753             : }
    1754             : 
    1755             : 
    1756             : /*
    1757             :   This test checks that 
    1758             : 
    1759             :   1) the server supports multiple locking contexts on the one SMB
    1760             :   connection, distinguished by PID.  
    1761             : 
    1762             :   2) the server correctly fails overlapping locks made by the same PID (this
    1763             :      goes against POSIX behaviour, which is why it is tricky to implement)
    1764             : 
    1765             :   3) the server denies unlock requests by an incorrect client PID
    1766             : */
    1767           5 : static bool run_locktest2(int dummy)
    1768             : {
    1769           0 :         static struct cli_state *cli;
    1770           5 :         const char *fname = "\\lockt2.lck";
    1771           0 :         uint16_t fnum1, fnum2, fnum3;
    1772           5 :         bool correct = True;
    1773           0 :         NTSTATUS status;
    1774             : 
    1775           5 :         if (!torture_open_connection(&cli, 0)) {
    1776           0 :                 return False;
    1777             :         }
    1778             : 
    1779           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1780             : 
    1781           5 :         printf("starting locktest2\n");
    1782             : 
    1783           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1784             : 
    1785           5 :         cli_setpid(cli, 1);
    1786             : 
    1787           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1788           5 :         if (!NT_STATUS_IS_OK(status)) {
    1789           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1790           0 :                 return False;
    1791             :         }
    1792             : 
    1793           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
    1794           5 :         if (!NT_STATUS_IS_OK(status)) {
    1795           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1796           0 :                 return False;
    1797             :         }
    1798             : 
    1799           5 :         cli_setpid(cli, 2);
    1800             : 
    1801           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
    1802           5 :         if (!NT_STATUS_IS_OK(status)) {
    1803           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1804           0 :                 return False;
    1805             :         }
    1806             : 
    1807           5 :         cli_setpid(cli, 1);
    1808             : 
    1809           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1810           5 :         if (!NT_STATUS_IS_OK(status)) {
    1811           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1812           0 :                 return false;
    1813             :         }
    1814             : 
    1815           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1816           5 :         if (NT_STATUS_IS_OK(status)) {
    1817           0 :                 printf("WRITE lock1 succeeded! This is a locking bug\n");
    1818           0 :                 correct = false;
    1819             :         } else {
    1820           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1821           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1822           0 :                         return false;
    1823             :                 }
    1824             :         }
    1825             : 
    1826           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
    1827           5 :         if (NT_STATUS_IS_OK(status)) {
    1828           0 :                 printf("WRITE lock2 succeeded! This is a locking bug\n");
    1829           0 :                 correct = false;
    1830             :         } else {
    1831           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1832           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1833           0 :                         return false;
    1834             :                 }
    1835             :         }
    1836             : 
    1837           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
    1838           5 :         if (NT_STATUS_IS_OK(status)) {
    1839           0 :                 printf("READ lock2 succeeded! This is a locking bug\n");
    1840           0 :                 correct = false;
    1841             :         } else {
    1842           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1843           5 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
    1844           0 :                         return false;
    1845             :                 }
    1846             :         }
    1847             : 
    1848           5 :         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
    1849           5 :         if (!NT_STATUS_IS_OK(status)) {
    1850           0 :                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
    1851             :         }
    1852           5 :         cli_setpid(cli, 2);
    1853           5 :         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
    1854           0 :                 printf("unlock at 100 succeeded! This is a locking bug\n");
    1855           0 :                 correct = False;
    1856             :         }
    1857             : 
    1858           5 :         status = cli_unlock(cli, fnum1, 0, 4);
    1859           5 :         if (NT_STATUS_IS_OK(status)) {
    1860           0 :                 printf("unlock1 succeeded! This is a locking bug\n");
    1861           0 :                 correct = false;
    1862             :         } else {
    1863           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1864           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1865           0 :                         return false;
    1866             :                 }
    1867             :         }
    1868             : 
    1869           5 :         status = cli_unlock(cli, fnum1, 0, 8);
    1870           5 :         if (NT_STATUS_IS_OK(status)) {
    1871           0 :                 printf("unlock2 succeeded! This is a locking bug\n");
    1872           0 :                 correct = false;
    1873             :         } else {
    1874           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1875           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1876           0 :                         return false;
    1877             :                 }
    1878             :         }
    1879             : 
    1880           5 :         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
    1881           5 :         if (NT_STATUS_IS_OK(status)) {
    1882           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1883           0 :                 correct = false;
    1884             :         } else {
    1885           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1886           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1887           0 :                         return false;
    1888             :                 }
    1889             :         }
    1890             : 
    1891           5 :         cli_setpid(cli, 1);
    1892             : 
    1893           5 :         status = cli_close(cli, fnum1);
    1894           5 :         if (!NT_STATUS_IS_OK(status)) {
    1895           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1896           0 :                 return False;
    1897             :         }
    1898             : 
    1899           5 :         status = cli_close(cli, fnum2);
    1900           5 :         if (!NT_STATUS_IS_OK(status)) {
    1901           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1902           0 :                 return False;
    1903             :         }
    1904             : 
    1905           5 :         status = cli_close(cli, fnum3);
    1906           5 :         if (!NT_STATUS_IS_OK(status)) {
    1907           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1908           0 :                 return False;
    1909             :         }
    1910             : 
    1911           5 :         if (!torture_close_connection(cli)) {
    1912           0 :                 correct = False;
    1913             :         }
    1914             : 
    1915           5 :         printf("locktest2 finished\n");
    1916             : 
    1917           5 :         return correct;
    1918             : }
    1919             : 
    1920             : 
    1921             : /*
    1922             :   This test checks that 
    1923             : 
    1924             :   1) the server supports the full offset range in lock requests
    1925             : */
    1926           5 : static bool run_locktest3(int dummy)
    1927             : {
    1928           0 :         static struct cli_state *cli1, *cli2;
    1929           5 :         const char *fname = "\\lockt3.lck";
    1930           0 :         uint16_t fnum1, fnum2;
    1931           0 :         int i;
    1932           0 :         uint32_t offset;
    1933           5 :         bool correct = True;
    1934           0 :         NTSTATUS status;
    1935             : 
    1936             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
    1937             : 
    1938           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1939           0 :                 return False;
    1940             :         }
    1941           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1942           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1943             : 
    1944           5 :         printf("starting locktest3\n");
    1945             : 
    1946           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1947             : 
    1948           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1949             :                          &fnum1);
    1950           5 :         if (!NT_STATUS_IS_OK(status)) {
    1951           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1952           0 :                 return False;
    1953             :         }
    1954             : 
    1955           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1956           5 :         if (!NT_STATUS_IS_OK(status)) {
    1957           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1958           0 :                 return False;
    1959             :         }
    1960             : 
    1961         505 :         for (offset=i=0;i<torture_numops;i++) {
    1962         500 :                 NEXT_OFFSET;
    1963             : 
    1964         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1965         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1966           0 :                         printf("lock1 %d failed (%s)\n", 
    1967             :                                i,
    1968             :                                nt_errstr(status));
    1969           0 :                         return False;
    1970             :                 }
    1971             : 
    1972         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1973         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1974           0 :                         printf("lock2 %d failed (%s)\n", 
    1975             :                                i,
    1976             :                                nt_errstr(status));
    1977           0 :                         return False;
    1978             :                 }
    1979             :         }
    1980             : 
    1981         505 :         for (offset=i=0;i<torture_numops;i++) {
    1982         500 :                 NEXT_OFFSET;
    1983             : 
    1984         500 :                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
    1985         500 :                 if (NT_STATUS_IS_OK(status)) {
    1986           0 :                         printf("error: lock1 %d succeeded!\n", i);
    1987           0 :                         return False;
    1988             :                 }
    1989             : 
    1990         500 :                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
    1991         500 :                 if (NT_STATUS_IS_OK(status)) {
    1992           0 :                         printf("error: lock2 %d succeeded!\n", i);
    1993           0 :                         return False;
    1994             :                 }
    1995             : 
    1996         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1997         500 :                 if (NT_STATUS_IS_OK(status)) {
    1998           0 :                         printf("error: lock3 %d succeeded!\n", i);
    1999           0 :                         return False;
    2000             :                 }
    2001             : 
    2002         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    2003         500 :                 if (NT_STATUS_IS_OK(status)) {
    2004           0 :                         printf("error: lock4 %d succeeded!\n", i);
    2005           0 :                         return False;
    2006             :                 }
    2007             :         }
    2008             : 
    2009         505 :         for (offset=i=0;i<torture_numops;i++) {
    2010         500 :                 NEXT_OFFSET;
    2011             : 
    2012         500 :                 status = cli_unlock(cli1, fnum1, offset-1, 1);
    2013         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2014           0 :                         printf("unlock1 %d failed (%s)\n", 
    2015             :                                i,
    2016             :                                nt_errstr(status));
    2017           0 :                         return False;
    2018             :                 }
    2019             : 
    2020         500 :                 status = cli_unlock(cli2, fnum2, offset-2, 1);
    2021         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2022           0 :                         printf("unlock2 %d failed (%s)\n", 
    2023             :                                i,
    2024             :                                nt_errstr(status));
    2025           0 :                         return False;
    2026             :                 }
    2027             :         }
    2028             : 
    2029           5 :         status = cli_close(cli1, fnum1);
    2030           5 :         if (!NT_STATUS_IS_OK(status)) {
    2031           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    2032           0 :                 return False;
    2033             :         }
    2034             : 
    2035           5 :         status = cli_close(cli2, fnum2);
    2036           5 :         if (!NT_STATUS_IS_OK(status)) {
    2037           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    2038           0 :                 return False;
    2039             :         }
    2040             : 
    2041           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2042           5 :         if (!NT_STATUS_IS_OK(status)) {
    2043           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    2044           0 :                 return False;
    2045             :         }
    2046             : 
    2047           5 :         if (!torture_close_connection(cli1)) {
    2048           0 :                 correct = False;
    2049             :         }
    2050             : 
    2051           5 :         if (!torture_close_connection(cli2)) {
    2052           0 :                 correct = False;
    2053             :         }
    2054             : 
    2055           5 :         printf("finished locktest3\n");
    2056             : 
    2057           5 :         return correct;
    2058             : }
    2059             : 
    2060          40 : static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
    2061             :                            char *buf, off_t offset, size_t size,
    2062             :                            size_t *nread, size_t expect)
    2063             : {
    2064           0 :         NTSTATUS status;
    2065           0 :         size_t l_nread;
    2066             : 
    2067          40 :         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
    2068             : 
    2069          40 :         if(!NT_STATUS_IS_OK(status)) {
    2070          20 :                 return false;
    2071          20 :         } else if (l_nread != expect) {
    2072           0 :                 return false;
    2073             :         }
    2074             : 
    2075          20 :         if (nread) {
    2076           0 :                 *nread = l_nread;
    2077             :         }
    2078             : 
    2079          20 :         return true;
    2080             : }
    2081             : 
    2082             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
    2083             :         printf("** "); correct = False; \
    2084             :         }
    2085             : 
    2086             : /*
    2087             :   looks at overlapping locks
    2088             : */
    2089           5 : static bool run_locktest4(int dummy)
    2090             : {
    2091           0 :         static struct cli_state *cli1, *cli2;
    2092           5 :         const char *fname = "\\lockt4.lck";
    2093           0 :         uint16_t fnum1, fnum2, f;
    2094           0 :         bool ret;
    2095           0 :         char buf[1000];
    2096           5 :         bool correct = True;
    2097           0 :         NTSTATUS status;
    2098             : 
    2099           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2100           0 :                 return False;
    2101             :         }
    2102             : 
    2103           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2104           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2105             : 
    2106           5 :         printf("starting locktest4\n");
    2107             : 
    2108           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2109             : 
    2110           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2111           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2112             : 
    2113           5 :         memset(buf, 0, sizeof(buf));
    2114             : 
    2115           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2116             :                               NULL);
    2117           5 :         if (!NT_STATUS_IS_OK(status)) {
    2118           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2119           0 :                 correct = False;
    2120           0 :                 goto fail;
    2121             :         }
    2122             : 
    2123          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2124           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
    2125           5 :         EXPECTED(ret, False);
    2126           5 :         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
    2127             : 
    2128          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
    2129           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
    2130           5 :         EXPECTED(ret, True);
    2131           5 :         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
    2132             : 
    2133          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
    2134           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
    2135           5 :         EXPECTED(ret, False);
    2136           5 :         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
    2137             : 
    2138          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
    2139           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
    2140           5 :         EXPECTED(ret, True);
    2141           5 :         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
    2142             : 
    2143           5 :         ret = (cli_setpid(cli1, 1),
    2144          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
    2145           5 :               (cli_setpid(cli1, 2),
    2146           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
    2147           5 :         EXPECTED(ret, False);
    2148           5 :         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
    2149             : 
    2150           5 :         ret = (cli_setpid(cli1, 1),
    2151          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
    2152           5 :               (cli_setpid(cli1, 2),
    2153           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
    2154           5 :         EXPECTED(ret, True);
    2155           5 :         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
    2156             : 
    2157          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
    2158           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
    2159           5 :         EXPECTED(ret, True);
    2160           5 :         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
    2161             : 
    2162          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
    2163           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
    2164           5 :         EXPECTED(ret, False);
    2165           5 :         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
    2166             : 
    2167          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
    2168           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
    2169           5 :         EXPECTED(ret, False);
    2170           5 :         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
    2171             : 
    2172          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
    2173           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
    2174           5 :         EXPECTED(ret, True);
    2175           5 :         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2176             : 
    2177           5 :         ret = (cli_setpid(cli1, 1),
    2178          10 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
    2179           5 :              (cli_setpid(cli1, 2),
    2180           5 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
    2181           5 :         EXPECTED(ret, False);
    2182           5 :         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2183             : 
    2184           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
    2185          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
    2186           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
    2187           5 :         EXPECTED(ret, False);
    2188           5 :         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
    2189             : 
    2190             : 
    2191          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
    2192           5 :               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
    2193           5 :         EXPECTED(ret, False);
    2194           5 :         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
    2195             : 
    2196           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2197           5 :         ret = NT_STATUS_IS_OK(status);
    2198           5 :         if (ret) {
    2199           5 :                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
    2200             :                                       NULL);
    2201           5 :                 ret = NT_STATUS_IS_OK(status);
    2202             :         }
    2203           5 :         EXPECTED(ret, False);
    2204           5 :         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
    2205             : 
    2206             : 
    2207           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2208           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2209          15 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
    2210           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
    2211           5 :         EXPECTED(ret, True);
    2212           5 :         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
    2213             : 
    2214             : 
    2215           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
    2216           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
    2217          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
    2218           5 :               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
    2219           5 :               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2220          10 :                                              150, 4, NULL))) &&
    2221           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
    2222           5 :         EXPECTED(ret, True);
    2223           5 :         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
    2224             : 
    2225           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
    2226           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
    2227           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2228          10 :                                            160, 4, NULL)) &&
    2229           5 :               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
    2230           5 :         EXPECTED(ret, True);
    2231           5 :         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
    2232             : 
    2233           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
    2234           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
    2235           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2236          10 :                                            170, 4, NULL)) &&
    2237           5 :               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
    2238           5 :         EXPECTED(ret, True);
    2239           5 :         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
    2240             : 
    2241           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
    2242           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
    2243           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
    2244           5 :               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2245          10 :                                             190, 4, NULL)) &&
    2246           5 :               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
    2247           5 :         EXPECTED(ret, True);
    2248           5 :         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
    2249             : 
    2250           5 :         cli_close(cli1, fnum1);
    2251           5 :         cli_close(cli2, fnum2);
    2252           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2253           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
    2254           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2255           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
    2256           5 :               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
    2257          15 :               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
    2258           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
    2259           5 :         cli_close(cli1, f);
    2260           5 :         cli_close(cli1, fnum1);
    2261           5 :         EXPECTED(ret, True);
    2262           5 :         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
    2263             : 
    2264           5 :  fail:
    2265           5 :         cli_close(cli1, fnum1);
    2266           5 :         cli_close(cli2, fnum2);
    2267           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2268           5 :         torture_close_connection(cli1);
    2269           5 :         torture_close_connection(cli2);
    2270             : 
    2271           5 :         printf("finished locktest4\n");
    2272           5 :         return correct;
    2273             : }
    2274             : 
    2275             : /*
    2276             :   looks at lock upgrade/downgrade.
    2277             : */
    2278           5 : static bool run_locktest5(int dummy)
    2279             : {
    2280           0 :         static struct cli_state *cli1, *cli2;
    2281           5 :         const char *fname = "\\lockt5.lck";
    2282           0 :         uint16_t fnum1, fnum2, fnum3;
    2283           0 :         bool ret;
    2284           0 :         char buf[1000];
    2285           5 :         bool correct = True;
    2286           0 :         NTSTATUS status;
    2287             : 
    2288           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2289           0 :                 return False;
    2290             :         }
    2291             : 
    2292           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2293           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2294             : 
    2295           5 :         printf("starting locktest5\n");
    2296             : 
    2297           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2298             : 
    2299           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2300           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2301           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
    2302             : 
    2303           5 :         memset(buf, 0, sizeof(buf));
    2304             : 
    2305           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2306             :                               NULL);
    2307           5 :         if (!NT_STATUS_IS_OK(status)) {
    2308           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2309           0 :                 correct = False;
    2310           0 :                 goto fail;
    2311             :         }
    2312             : 
    2313             :         /* Check for NT bug... */
    2314          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2315           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
    2316           5 :         cli_close(cli1, fnum1);
    2317           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2318           5 :         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
    2319           5 :         ret = NT_STATUS_IS_OK(status);
    2320           5 :         EXPECTED(ret, True);
    2321           5 :         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
    2322           5 :         cli_close(cli1, fnum1);
    2323           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2324           5 :         cli_unlock(cli1, fnum3, 0, 1);
    2325             : 
    2326          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2327           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
    2328           5 :         EXPECTED(ret, True);
    2329           5 :         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
    2330             : 
    2331           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
    2332           5 :         ret = NT_STATUS_IS_OK(status);
    2333           5 :         EXPECTED(ret, False);
    2334             : 
    2335           5 :         printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
    2336             : 
    2337             :         /* Unlock the process 2 lock. */
    2338           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2339             : 
    2340           5 :         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
    2341           5 :         ret = NT_STATUS_IS_OK(status);
    2342           5 :         EXPECTED(ret, False);
    2343             : 
    2344           5 :         printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
    2345             : 
    2346             :         /* Unlock the process 1 fnum3 lock. */
    2347           5 :         cli_unlock(cli1, fnum3, 0, 4);
    2348             : 
    2349             :         /* Stack 2 more locks here. */
    2350          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
    2351           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
    2352             : 
    2353           5 :         EXPECTED(ret, True);
    2354           5 :         printf("the same process %s stack read locks\n", ret?"can":"cannot");
    2355             : 
    2356             :         /* Unlock the first process lock, then check this was the WRITE lock that was
    2357             :                 removed. */
    2358             : 
    2359          10 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2360           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
    2361             : 
    2362           5 :         EXPECTED(ret, True);
    2363           5 :         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
    2364             : 
    2365             :         /* Unlock the process 2 lock. */
    2366           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2367             : 
    2368             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
    2369             : 
    2370           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
    2371          10 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2372           5 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2373             : 
    2374           5 :         EXPECTED(ret, True);
    2375           5 :         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
    2376             : 
    2377             :         /* Ensure the next unlock fails. */
    2378           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2379           5 :         EXPECTED(ret, False);
    2380           5 :         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
    2381             : 
    2382             :         /* Ensure connection 2 can get a write lock. */
    2383           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
    2384           5 :         ret = NT_STATUS_IS_OK(status);
    2385           5 :         EXPECTED(ret, True);
    2386             : 
    2387           5 :         printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
    2388             : 
    2389             : 
    2390           5 :  fail:
    2391           5 :         cli_close(cli1, fnum1);
    2392           5 :         cli_close(cli2, fnum2);
    2393           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2394           5 :         if (!torture_close_connection(cli1)) {
    2395           0 :                 correct = False;
    2396             :         }
    2397           5 :         if (!torture_close_connection(cli2)) {
    2398           0 :                 correct = False;
    2399             :         }
    2400             : 
    2401           5 :         printf("finished locktest5\n");
    2402             : 
    2403           5 :         return correct;
    2404             : }
    2405             : 
    2406             : /*
    2407             :   tries the unusual lockingX locktype bits
    2408             : */
    2409           5 : static bool run_locktest6(int dummy)
    2410             : {
    2411           0 :         static struct cli_state *cli;
    2412           5 :         const char *fname[1] = { "\\lock6.txt" };
    2413           0 :         int i;
    2414           0 :         uint16_t fnum;
    2415           0 :         NTSTATUS status;
    2416             : 
    2417           5 :         if (!torture_open_connection(&cli, 0)) {
    2418           0 :                 return False;
    2419             :         }
    2420             : 
    2421           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    2422             : 
    2423           5 :         printf("starting locktest6\n");
    2424             : 
    2425          10 :         for (i=0;i<1;i++) {
    2426           5 :                 printf("Testing %s\n", fname[i]);
    2427             : 
    2428           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2429             : 
    2430           5 :                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    2431           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
    2432           5 :                 cli_close(cli, fnum);
    2433           5 :                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
    2434             : 
    2435           5 :                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
    2436           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
    2437           5 :                 cli_close(cli, fnum);
    2438           5 :                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
    2439             : 
    2440           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2441             :         }
    2442             : 
    2443           5 :         torture_close_connection(cli);
    2444             : 
    2445           5 :         printf("finished locktest6\n");
    2446           5 :         return True;
    2447             : }
    2448             : 
    2449           5 : static bool run_locktest7(int dummy)
    2450             : {
    2451           0 :         struct cli_state *cli1;
    2452           5 :         const char *fname = "\\lockt7.lck";
    2453           0 :         uint16_t fnum1;
    2454           0 :         char buf[200];
    2455           5 :         bool correct = False;
    2456           0 :         size_t nread;
    2457           0 :         NTSTATUS status;
    2458             : 
    2459           5 :         if (!torture_open_connection(&cli1, 0)) {
    2460           0 :                 return False;
    2461             :         }
    2462             : 
    2463           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2464             : 
    2465           5 :         printf("starting locktest7\n");
    2466             : 
    2467           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2468             : 
    2469           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2470             : 
    2471           5 :         memset(buf, 0, sizeof(buf));
    2472             : 
    2473           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2474             :                               NULL);
    2475           5 :         if (!NT_STATUS_IS_OK(status)) {
    2476           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2477           0 :                 goto fail;
    2478             :         }
    2479             : 
    2480           5 :         cli_setpid(cli1, 1);
    2481             : 
    2482           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2483           5 :         if (!NT_STATUS_IS_OK(status)) {
    2484           0 :                 printf("Unable to apply read lock on range 130:4, "
    2485             :                        "error was %s\n", nt_errstr(status));
    2486           0 :                 goto fail;
    2487             :         } else {
    2488           5 :                 printf("pid1 successfully locked range 130:4 for READ\n");
    2489             :         }
    2490             : 
    2491           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2492           5 :         if (!NT_STATUS_IS_OK(status)) {
    2493           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2494             :                       nt_errstr(status));
    2495           0 :                 goto fail;
    2496           5 :         } else if (nread != 4) {
    2497           0 :                 printf("pid1 unable to read the range 130:4, "
    2498             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2499           0 :                 goto fail;
    2500             :         } else {
    2501           5 :                 printf("pid1 successfully read the range 130:4\n");
    2502             :         }
    2503             : 
    2504           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2505           5 :         if (!NT_STATUS_IS_OK(status)) {
    2506           5 :                 printf("pid1 unable to write to the range 130:4, error was "
    2507             :                        "%s\n", nt_errstr(status));
    2508           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2509           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2510           0 :                         goto fail;
    2511             :                 }
    2512             :         } else {
    2513           0 :                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
    2514           0 :                 goto fail;
    2515             :         }
    2516             : 
    2517           5 :         cli_setpid(cli1, 2);
    2518             : 
    2519           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2520           5 :         if (!NT_STATUS_IS_OK(status)) {
    2521           0 :                 printf("pid2 unable to read the range 130:4, error was %s\n",
    2522             :                       nt_errstr(status));
    2523           0 :                 goto fail;
    2524           5 :         } else if (nread != 4) {
    2525           0 :                 printf("pid2 unable to read the range 130:4, "
    2526             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2527           0 :                 goto fail;
    2528             :         } else {
    2529           5 :                 printf("pid2 successfully read the range 130:4\n");
    2530             :         }
    2531             : 
    2532           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2533           5 :         if (!NT_STATUS_IS_OK(status)) {
    2534           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2535             :                        "%s\n", nt_errstr(status));
    2536           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2537           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2538           0 :                         goto fail;
    2539             :                 }
    2540             :         } else {
    2541           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2542           0 :                 goto fail;
    2543             :         }
    2544             : 
    2545           5 :         cli_setpid(cli1, 1);
    2546           5 :         cli_unlock(cli1, fnum1, 130, 4);
    2547             : 
    2548           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
    2549           5 :         if (!NT_STATUS_IS_OK(status)) {
    2550           0 :                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
    2551           0 :                 goto fail;
    2552             :         } else {
    2553           5 :                 printf("pid1 successfully locked range 130:4 for WRITE\n");
    2554             :         }
    2555             : 
    2556           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2557           5 :         if (!NT_STATUS_IS_OK(status)) {
    2558           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2559             :                       nt_errstr(status));
    2560           0 :                 goto fail;
    2561           5 :         } else if (nread != 4) {
    2562           0 :                 printf("pid1 unable to read the range 130:4, "
    2563             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2564           0 :                 goto fail;
    2565             :         } else {
    2566           5 :                 printf("pid1 successfully read the range 130:4\n");
    2567             :         }
    2568             : 
    2569           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2570           5 :         if (!NT_STATUS_IS_OK(status)) {
    2571           0 :                 printf("pid1 unable to write to the range 130:4, error was "
    2572             :                        "%s\n", nt_errstr(status));
    2573           0 :                 goto fail;
    2574             :         } else {
    2575           5 :                 printf("pid1 successfully wrote to the range 130:4\n");
    2576             :         }
    2577             : 
    2578           5 :         cli_setpid(cli1, 2);
    2579             : 
    2580           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2581           5 :         if (!NT_STATUS_IS_OK(status)) {
    2582           5 :                 printf("pid2 unable to read the range 130:4, error was "
    2583             :                        "%s\n", nt_errstr(status));
    2584           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2585           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2586           0 :                         goto fail;
    2587             :                 }
    2588             :         } else {
    2589           0 :                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
    2590             :                        (unsigned long)nread);
    2591           0 :                 goto fail;
    2592             :         }
    2593             : 
    2594           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2595           5 :         if (!NT_STATUS_IS_OK(status)) {
    2596           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2597             :                        "%s\n", nt_errstr(status));
    2598           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2599           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2600           0 :                         goto fail;
    2601             :                 }
    2602             :         } else {
    2603           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2604           0 :                 goto fail;
    2605             :         }
    2606             : 
    2607           5 :         cli_unlock(cli1, fnum1, 130, 0);
    2608           5 :         correct = True;
    2609             : 
    2610           5 : fail:
    2611           5 :         cli_close(cli1, fnum1);
    2612           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2613           5 :         torture_close_connection(cli1);
    2614             : 
    2615           5 :         printf("finished locktest7\n");
    2616           5 :         return correct;
    2617             : }
    2618             : 
    2619             : /*
    2620             :  * This demonstrates a problem with our use of GPFS share modes: A file
    2621             :  * descriptor sitting in the pending close queue holding a GPFS share mode
    2622             :  * blocks opening a file another time. Happens with Word 2007 temp files.
    2623             :  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
    2624             :  * open is denied with NT_STATUS_SHARING_VIOLATION.
    2625             :  */
    2626             : 
    2627           0 : static bool run_locktest8(int dummy)
    2628             : {
    2629           0 :         struct cli_state *cli1;
    2630           0 :         const char *fname = "\\lockt8.lck";
    2631           0 :         uint16_t fnum1, fnum2;
    2632           0 :         char buf[200];
    2633           0 :         bool correct = False;
    2634           0 :         NTSTATUS status;
    2635             : 
    2636           0 :         if (!torture_open_connection(&cli1, 0)) {
    2637           0 :                 return False;
    2638             :         }
    2639             : 
    2640           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2641             : 
    2642           0 :         printf("starting locktest8\n");
    2643             : 
    2644           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2645             : 
    2646           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
    2647             :                           &fnum1);
    2648           0 :         if (!NT_STATUS_IS_OK(status)) {
    2649           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2650           0 :                 return false;
    2651             :         }
    2652             : 
    2653           0 :         memset(buf, 0, sizeof(buf));
    2654             : 
    2655           0 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
    2656           0 :         if (!NT_STATUS_IS_OK(status)) {
    2657           0 :                 d_fprintf(stderr, "cli_openx second time returned %s\n",
    2658             :                           nt_errstr(status));
    2659           0 :                 goto fail;
    2660             :         }
    2661             : 
    2662           0 :         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
    2663           0 :         if (!NT_STATUS_IS_OK(status)) {
    2664           0 :                 printf("Unable to apply read lock on range 1:1, error was "
    2665             :                        "%s\n", nt_errstr(status));
    2666           0 :                 goto fail;
    2667             :         }
    2668             : 
    2669           0 :         status = cli_close(cli1, fnum1);
    2670           0 :         if (!NT_STATUS_IS_OK(status)) {
    2671           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2672           0 :                 goto fail;
    2673             :         }
    2674             : 
    2675           0 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2676           0 :         if (!NT_STATUS_IS_OK(status)) {
    2677           0 :                 d_fprintf(stderr, "cli_openx third time returned %s\n",
    2678             :                           nt_errstr(status));
    2679           0 :                 goto fail;
    2680             :         }
    2681             : 
    2682           0 :         correct = true;
    2683             : 
    2684           0 : fail:
    2685           0 :         cli_close(cli1, fnum1);
    2686           0 :         cli_close(cli1, fnum2);
    2687           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2688           0 :         torture_close_connection(cli1);
    2689             : 
    2690           0 :         printf("finished locktest8\n");
    2691           0 :         return correct;
    2692             : }
    2693             : 
    2694             : /*
    2695             :  * This test is designed to be run in conjunction with
    2696             :  * external NFS or POSIX locks taken in the filesystem.
    2697             :  * It checks that the smbd server will block until the
    2698             :  * lock is released and then acquire it. JRA.
    2699             :  */
    2700             : 
    2701             : static bool got_alarm;
    2702             : static struct cli_state *alarm_cli;
    2703             : 
    2704           0 : static void alarm_handler(int dummy)
    2705             : {
    2706           0 :         got_alarm = True;
    2707           0 : }
    2708             : 
    2709           0 : static void alarm_handler_parent(int dummy)
    2710             : {
    2711           0 :         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    2712           0 : }
    2713             : 
    2714           8 : static void do_local_lock(const char *fname, int read_fd, int write_fd)
    2715             : {
    2716           0 :         int fd;
    2717           8 :         char c = '\0';
    2718           0 :         struct flock lock;
    2719           8 :         const char *local_pathname = NULL;
    2720           0 :         int ret;
    2721             : 
    2722           8 :         local_pathname = talloc_asprintf(talloc_tos(),
    2723             :                         "%s/%s", local_path, fname);
    2724           8 :         if (!local_pathname) {
    2725           0 :                 printf("child: alloc fail\n");
    2726           0 :                 exit(1);
    2727             :         }
    2728             : 
    2729           8 :         unlink(local_pathname);
    2730           8 :         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
    2731           8 :         if (fd == -1) {
    2732           0 :                 printf("child: open of %s failed %s.\n",
    2733           0 :                         local_pathname, strerror(errno));
    2734           0 :                 exit(1);
    2735             :         }
    2736             : 
    2737             :         /* Now take a fcntl lock. */
    2738           8 :         lock.l_type = F_WRLCK;
    2739           8 :         lock.l_whence = SEEK_SET;
    2740           8 :         lock.l_start = 0;
    2741           8 :         lock.l_len = 4;
    2742           8 :         lock.l_pid = getpid();
    2743             : 
    2744           8 :         ret = fcntl(fd,F_SETLK,&lock);
    2745           8 :         if (ret == -1) {
    2746           0 :                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
    2747           0 :                         local_pathname, strerror(errno));
    2748           0 :                 exit(1);
    2749             :         } else {
    2750           8 :                 printf("child: got lock 0:4 on file %s.\n",
    2751             :                         local_pathname );
    2752           8 :                 fflush(stdout);
    2753             :         }
    2754             : 
    2755           8 :         CatchSignal(SIGALRM, alarm_handler);
    2756           8 :         alarm(5);
    2757             :         /* Signal the parent. */
    2758           8 :         if (write(write_fd, &c, 1) != 1) {
    2759           0 :                 printf("child: start signal fail %s.\n",
    2760           0 :                         strerror(errno));
    2761           0 :                 exit(1);
    2762             :         }
    2763           8 :         alarm(0);
    2764             : 
    2765           8 :         alarm(10);
    2766             :         /* Wait for the parent to be ready. */
    2767           8 :         if (read(read_fd, &c, 1) != 1) {
    2768           0 :                 printf("child: reply signal fail %s.\n",
    2769           0 :                         strerror(errno));
    2770           0 :                 exit(1);
    2771             :         }
    2772           8 :         alarm(0);
    2773             : 
    2774           8 :         sleep(5);
    2775           8 :         close(fd);
    2776           8 :         printf("child: released lock 0:4 on file %s.\n",
    2777             :                 local_pathname );
    2778           8 :         fflush(stdout);
    2779           8 :         exit(0);
    2780             : }
    2781             : 
    2782           8 : static bool _run_locktest9X(const char *fname, int timeout)
    2783             : {
    2784           0 :         struct cli_state *cli1;
    2785           8 :         char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname);
    2786           0 :         uint16_t fnum;
    2787           8 :         bool correct = False;
    2788           0 :         int pipe_in[2], pipe_out[2];
    2789           0 :         pid_t child_pid;
    2790           8 :         char c = '\0';
    2791           0 :         int ret;
    2792           0 :         struct timeval start;
    2793           0 :         double seconds;
    2794           0 :         NTSTATUS status;
    2795             : 
    2796           8 :         printf("starting locktest9X: %s\n", fname);
    2797             : 
    2798           8 :         if (local_path == NULL) {
    2799           0 :                 d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n");
    2800           0 :                 return false;
    2801             :         }
    2802             : 
    2803           8 :         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
    2804           0 :                 return false;
    2805             :         }
    2806             : 
    2807           8 :         child_pid = fork();
    2808          16 :         if (child_pid == -1) {
    2809           0 :                 return false;
    2810             :         }
    2811             : 
    2812          16 :         if (child_pid == 0) {
    2813             :                 /* Child. */
    2814           8 :                 do_local_lock(fname, pipe_out[0], pipe_in[1]);
    2815           0 :                 exit(0);
    2816             :         }
    2817             : 
    2818           8 :         close(pipe_out[0]);
    2819           8 :         close(pipe_in[1]);
    2820           8 :         pipe_out[0] = -1;
    2821           8 :         pipe_in[1] = -1;
    2822             : 
    2823             :         /* Parent. */
    2824           8 :         ret = read(pipe_in[0], &c, 1);
    2825           8 :         if (ret != 1) {
    2826           0 :                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
    2827           0 :                         strerror(errno));
    2828           0 :                 return false;
    2829             :         }
    2830             : 
    2831           8 :         if (!torture_open_connection(&cli1, 0)) {
    2832           0 :                 return false;
    2833             :         }
    2834             : 
    2835           8 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2836             : 
    2837           8 :         status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE,
    2838             :                           &fnum);
    2839           8 :         if (!NT_STATUS_IS_OK(status)) {
    2840           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2841           0 :                 return false;
    2842             :         }
    2843             : 
    2844             :         /* Ensure the child has the lock. */
    2845           8 :         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
    2846           8 :         if (NT_STATUS_IS_OK(status)) {
    2847           0 :                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
    2848           0 :                 goto fail;
    2849             :         } else {
    2850           8 :                 d_printf("Child has the lock.\n");
    2851             :         }
    2852             : 
    2853             :         /* Tell the child to wait 5 seconds then exit. */
    2854           8 :         ret = write(pipe_out[1], &c, 1);
    2855           8 :         if (ret != 1) {
    2856           0 :                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
    2857           0 :                         strerror(errno));
    2858           0 :                 goto fail;
    2859             :         }
    2860             : 
    2861             :         /* Wait 20 seconds for the lock. */
    2862           8 :         alarm_cli = cli1;
    2863           8 :         CatchSignal(SIGALRM, alarm_handler_parent);
    2864           8 :         alarm(20);
    2865             : 
    2866           8 :         start = timeval_current();
    2867             : 
    2868           8 :         status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK);
    2869           8 :         if (!NT_STATUS_IS_OK(status)) {
    2870           0 :                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
    2871             :                        "%s\n", nt_errstr(status));
    2872           0 :                 goto fail_nofd;
    2873             :         }
    2874           8 :         alarm(0);
    2875             : 
    2876           8 :         seconds = timeval_elapsed(&start);
    2877             : 
    2878           8 :         printf("Parent got the lock after %.2f seconds.\n",
    2879             :                 seconds);
    2880             : 
    2881           8 :         status = cli_close(cli1, fnum);
    2882           8 :         if (!NT_STATUS_IS_OK(status)) {
    2883           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2884           0 :                 goto fail;
    2885             :         }
    2886             : 
    2887           8 :         correct = true;
    2888             : 
    2889           8 : fail:
    2890           8 :         cli_close(cli1, fnum);
    2891           8 :         torture_close_connection(cli1);
    2892             : 
    2893           8 : fail_nofd:
    2894             : 
    2895           8 :         printf("finished locktest9X: %s\n", fname);
    2896           8 :         return correct;
    2897             : }
    2898             : 
    2899           4 : static bool run_locktest9a(int dummy)
    2900             : {
    2901           4 :         return _run_locktest9X("lock9a.dat", -1);
    2902             : }
    2903             : 
    2904           4 : static bool run_locktest9b(int dummy)
    2905             : {
    2906           4 :         return _run_locktest9X("lock9b.dat", 10000);
    2907             : }
    2908             : 
    2909             : struct locktest10_state {
    2910             :         bool ok;
    2911             :         bool done;
    2912             : };
    2913             : 
    2914             : static void locktest10_lockingx_done(struct tevent_req *subreq);
    2915             : static void locktest10_read_andx_done(struct tevent_req *subreq);
    2916             : 
    2917           5 : static bool run_locktest10(int dummy)
    2918             : {
    2919           5 :         struct tevent_context *ev = NULL;
    2920           5 :         struct cli_state *cli1 = NULL;
    2921           5 :         struct cli_state *cli2 = NULL;
    2922           5 :         struct smb1_lock_element lck = { 0 };
    2923           5 :         struct tevent_req *reqs[2] = { NULL };
    2924           5 :         struct tevent_req *smbreqs[2] = { NULL };
    2925           5 :         const char fname[] = "\\lockt10.lck";
    2926           0 :         uint16_t fnum1, fnum2;
    2927           5 :         bool ret = false;
    2928           0 :         bool ok;
    2929           5 :         uint8_t data = 1;
    2930           5 :         struct locktest10_state state = { .ok = true };
    2931           0 :         NTSTATUS status;
    2932             : 
    2933           5 :         printf("starting locktest10\n");
    2934             : 
    2935           5 :         ev = samba_tevent_context_init(NULL);
    2936           5 :         if (ev == NULL) {
    2937           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    2938           0 :                 goto done;
    2939             :         }
    2940             : 
    2941           5 :         ok = torture_open_connection(&cli1, 0);
    2942           5 :         if (!ok) {
    2943           0 :                 goto done;
    2944             :         }
    2945           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2946             : 
    2947           5 :         ok = torture_open_connection(&cli2, 1);
    2948           5 :         if (!ok) {
    2949           0 :                 goto done;
    2950             :         }
    2951           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2952             : 
    2953           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    2954           5 :         if (!NT_STATUS_IS_OK(status)) {
    2955           0 :                 d_fprintf(stderr,
    2956             :                           "cli_openx failed: %s\n",
    2957             :                           nt_errstr(status));
    2958           0 :                 goto done;
    2959             :         }
    2960             : 
    2961           5 :         status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
    2962           5 :         if (!NT_STATUS_IS_OK(status)) {
    2963           0 :                 d_fprintf(stderr,
    2964             :                           "cli_writeall failed: %s\n",
    2965             :                           nt_errstr(status));
    2966           0 :                 goto done;
    2967             :         }
    2968             : 
    2969           5 :         status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    2970           5 :         if (!NT_STATUS_IS_OK(status)) {
    2971           0 :                 d_fprintf(stderr,
    2972             :                           "cli_openx failed: %s\n",
    2973             :                           nt_errstr(status));
    2974           0 :                 goto done;
    2975             :         }
    2976             : 
    2977           5 :         status = cli_locktype(
    2978             :                 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    2979           5 :         if (!NT_STATUS_IS_OK(status)) {
    2980           0 :                 d_fprintf(stderr,
    2981             :                           "cli_locktype failed: %s\n",
    2982             :                           nt_errstr(status));
    2983           0 :                 goto done;
    2984             :         }
    2985             : 
    2986           5 :         lck = (struct smb1_lock_element) {
    2987           5 :                 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
    2988             :         };
    2989             : 
    2990           5 :         reqs[0] = cli_lockingx_create(
    2991             :                 ev,                             /* mem_ctx */
    2992             :                 ev,                             /* tevent_context */
    2993             :                 cli1,                           /* cli */
    2994             :                 fnum1,                          /* fnum */
    2995             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    2996             :                 0,                              /* newoplocklevel */
    2997             :                 1,                              /* timeout */
    2998             :                 0,                              /* num_unlocks */
    2999             :                 NULL,                           /* unlocks */
    3000             :                 1,                              /* num_locks */
    3001             :                 &lck,                               /* locks */
    3002             :                 &smbreqs[0]);                       /* psmbreq */
    3003           5 :         if (reqs[0] == NULL) {
    3004           0 :                 d_fprintf(stderr, "cli_lockingx_create failed\n");
    3005           0 :                 goto done;
    3006             :         }
    3007           5 :         tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
    3008             : 
    3009           5 :         reqs[1] = cli_read_andx_create(
    3010             :                 ev,             /* mem_ctx */
    3011             :                 ev,             /* ev */
    3012             :                 cli1,           /* cli */
    3013             :                 fnum1,          /* fnum */
    3014             :                 0,              /* offset */
    3015             :                 1,              /* size */
    3016             :                 &smbreqs[1]);       /* psmbreq */
    3017           5 :         if (reqs[1] == NULL) {
    3018           0 :                 d_fprintf(stderr, "cli_read_andx_create failed\n");
    3019           0 :                 goto done;
    3020             :         }
    3021           5 :         tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
    3022             : 
    3023           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
    3024           5 :         if (!NT_STATUS_IS_OK(status)) {
    3025           0 :                 d_fprintf(stderr,
    3026             :                           "smb1cli_req_chain_submit failed: %s\n",
    3027             :                           nt_errstr(status));
    3028           0 :                 goto done;
    3029             :         }
    3030             : 
    3031          30 :         while (!state.done) {
    3032          25 :                 tevent_loop_once(ev);
    3033             :         }
    3034             : 
    3035           5 :         torture_close_connection(cli1);
    3036             : 
    3037           5 :         if (state.ok) {
    3038           5 :                 ret = true;
    3039             :         }
    3040           0 : done:
    3041           5 :         return ret;
    3042             : }
    3043             : 
    3044           5 : static void locktest10_lockingx_done(struct tevent_req *subreq)
    3045             : {
    3046           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3047           0 :         NTSTATUS status;
    3048             : 
    3049           5 :         status = cli_lockingx_recv(subreq);
    3050           5 :         TALLOC_FREE(subreq);
    3051             : 
    3052           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3053           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3054           0 :                 state->ok = false;
    3055             :         }
    3056           5 : }
    3057             : 
    3058           5 : static void locktest10_read_andx_done(struct tevent_req *subreq)
    3059             : {
    3060           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3061           5 :         ssize_t received = -1;
    3062           5 :         uint8_t *rcvbuf = NULL;
    3063           0 :         NTSTATUS status;
    3064             : 
    3065           5 :         status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3066             : 
    3067           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
    3068           0 :                 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
    3069           0 :                 state->ok = false;
    3070             :         }
    3071             : 
    3072           5 :         state->done = true;
    3073           5 :         TALLOC_FREE(subreq);
    3074           5 : }
    3075             : 
    3076           5 : static bool run_locktest11(int dummy)
    3077             : {
    3078           0 :         struct cli_state *cli1;
    3079           5 :         const char *fname = "\\lockt11.lck";
    3080           0 :         NTSTATUS status;
    3081           0 :         uint16_t fnum;
    3082           5 :         bool ret = false;
    3083             : 
    3084           5 :         if (!torture_open_connection(&cli1, 0)) {
    3085           0 :                 return false;
    3086             :         }
    3087             : 
    3088           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3089             : 
    3090           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3091             : 
    3092           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
    3093           5 :         if (!NT_STATUS_IS_OK(status)) {
    3094           0 :                 d_fprintf(stderr,
    3095             :                           "cli_openx returned %s\n",
    3096             :                           nt_errstr(status));
    3097           0 :                 return false;
    3098             :         }
    3099             : 
    3100             :         /*
    3101             :          * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
    3102             :          * returns NT_STATUS_OK
    3103             :          */
    3104             : 
    3105           5 :         status = cli_lockingx(
    3106             :                 cli1,                           /* cli */
    3107             :                 fnum,                           /* fnum */
    3108             :                 LOCKING_ANDX_CANCEL_LOCK,       /* typeoflock */
    3109             :                 0,                              /* newoplocklevel */
    3110             :                 0,                              /* timeout */
    3111             :                 0,                              /* num_unlocks */
    3112             :                 NULL,                           /* unlocks */
    3113             :                 0,                              /* num_locks */
    3114             :                 NULL);                          /* locks */
    3115             : 
    3116           5 :         if (!NT_STATUS_IS_OK(status)) {
    3117           1 :                 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
    3118           1 :                 goto fail;
    3119             :         }
    3120             : 
    3121           4 :         ret = true;
    3122           5 : fail:
    3123           5 :         cli_close(cli1, fnum);
    3124           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3125             : 
    3126           5 :         return ret;
    3127             : }
    3128             : 
    3129             : struct deferred_close_state {
    3130             :         struct tevent_context *ev;
    3131             :         struct cli_state *cli;
    3132             :         uint16_t fnum;
    3133             : };
    3134             : 
    3135             : static void deferred_close_waited(struct tevent_req *subreq);
    3136             : static void deferred_close_done(struct tevent_req *subreq);
    3137             : 
    3138           5 : static struct tevent_req *deferred_close_send(
    3139             :         TALLOC_CTX *mem_ctx,
    3140             :         struct tevent_context *ev,
    3141             :         int wait_secs,
    3142             :         struct cli_state *cli,
    3143             :         uint16_t fnum)
    3144             : {
    3145           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3146           5 :         struct deferred_close_state *state = NULL;
    3147           5 :         struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
    3148             : 
    3149           5 :         req = tevent_req_create(
    3150             :                 mem_ctx, &state, struct deferred_close_state);
    3151           5 :         if (req == NULL) {
    3152           0 :                 return NULL;
    3153             :         }
    3154           5 :         state->ev = ev;
    3155           5 :         state->cli = cli;
    3156           5 :         state->fnum = fnum;
    3157             : 
    3158           5 :         subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
    3159           5 :         if (tevent_req_nomem(subreq, req)) {
    3160           0 :                 return tevent_req_post(req, ev);
    3161             :         }
    3162           5 :         tevent_req_set_callback(subreq, deferred_close_waited, req);
    3163           5 :         return req;
    3164             : }
    3165             : 
    3166           5 : static void deferred_close_waited(struct tevent_req *subreq)
    3167             : {
    3168           5 :         struct tevent_req *req = tevent_req_callback_data(
    3169             :                 subreq, struct tevent_req);
    3170           5 :         struct deferred_close_state *state = tevent_req_data(
    3171             :                 req, struct deferred_close_state);
    3172           0 :         bool ok;
    3173             : 
    3174           5 :         ok = tevent_wakeup_recv(subreq);
    3175           5 :         TALLOC_FREE(subreq);
    3176           5 :         if (!ok) {
    3177           0 :                 tevent_req_oom(req);
    3178           0 :                 return;
    3179             :         }
    3180             : 
    3181           5 :         subreq = cli_close_send(state, state->ev, state->cli, state->fnum, 0);
    3182           5 :         if (tevent_req_nomem(subreq, req)) {
    3183           0 :                 return;
    3184             :         }
    3185           5 :         tevent_req_set_callback(subreq, deferred_close_done, req);
    3186             : }
    3187             : 
    3188           5 : static void deferred_close_done(struct tevent_req *subreq)
    3189             : {
    3190           5 :         NTSTATUS status = cli_close_recv(subreq);
    3191           5 :         tevent_req_simple_finish_ntstatus(subreq, status);
    3192           5 : }
    3193             : 
    3194           5 : static NTSTATUS deferred_close_recv(struct tevent_req *req)
    3195             : {
    3196           5 :         return tevent_req_simple_recv_ntstatus(req);
    3197             : }
    3198             : 
    3199             : struct lockread_state {
    3200             :         struct smb1_lock_element lck;
    3201             :         struct tevent_req *reqs[2];
    3202             :         struct tevent_req *smbreqs[2];
    3203             :         NTSTATUS lock_status;
    3204             :         NTSTATUS read_status;
    3205             :         uint8_t *readbuf;
    3206             : };
    3207             : 
    3208             : static void lockread_lockingx_done(struct tevent_req *subreq);
    3209             : static void lockread_read_andx_done(struct tevent_req *subreq);
    3210             : 
    3211           5 : static struct tevent_req *lockread_send(
    3212             :         TALLOC_CTX *mem_ctx,
    3213             :         struct tevent_context *ev,
    3214             :         struct cli_state *cli,
    3215             :         uint16_t fnum)
    3216             : {
    3217           5 :         struct tevent_req *req = NULL;
    3218           5 :         struct lockread_state *state = NULL;
    3219           0 :         NTSTATUS status;
    3220             : 
    3221           5 :         req = tevent_req_create(mem_ctx, &state, struct lockread_state);
    3222           5 :         if (req == NULL) {
    3223           0 :                 return NULL;
    3224             :         }
    3225             : 
    3226          10 :         state->lck = (struct smb1_lock_element) {
    3227           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3228             :         };
    3229             : 
    3230          10 :         state->reqs[0] = cli_lockingx_create(
    3231             :                 ev,                             /* mem_ctx */
    3232             :                 ev,                             /* tevent_context */
    3233             :                 cli,                            /* cli */
    3234             :                 fnum,                           /* fnum */
    3235             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3236             :                 0,                              /* newoplocklevel */
    3237             :                 10000,                          /* timeout */
    3238             :                 0,                              /* num_unlocks */
    3239             :                 NULL,                           /* unlocks */
    3240             :                 1,                              /* num_locks */
    3241           5 :                 &state->lck,                     /* locks */
    3242           5 :                 &state->smbreqs[0]);             /* psmbreq */
    3243           5 :         if (tevent_req_nomem(state->reqs[0], req)) {
    3244           0 :                 return tevent_req_post(req, ev);
    3245             :         }
    3246           5 :         tevent_req_set_callback(
    3247             :                 state->reqs[0], lockread_lockingx_done, req);
    3248             : 
    3249          10 :         state->reqs[1] = cli_read_andx_create(
    3250             :                 ev,             /* mem_ctx */
    3251             :                 ev,             /* ev */
    3252             :                 cli,            /* cli */
    3253             :                 fnum,           /* fnum */
    3254             :                 0,              /* offset */
    3255             :                 1,              /* size */
    3256           5 :                 &state->smbreqs[1]);     /* psmbreq */
    3257           5 :         if (tevent_req_nomem(state->reqs[1], req)) {
    3258           0 :                 return tevent_req_post(req, ev);
    3259             :         }
    3260           5 :         tevent_req_set_callback(
    3261             :                 state->reqs[1], lockread_read_andx_done, req);
    3262             : 
    3263           5 :         status = smb1cli_req_chain_submit(state->smbreqs, 2);
    3264           5 :         if (tevent_req_nterror(req, status)) {
    3265           0 :                 return tevent_req_post(req, ev);
    3266             :         }
    3267           5 :         return req;
    3268             : }
    3269             : 
    3270           5 : static void lockread_lockingx_done(struct tevent_req *subreq)
    3271             : {
    3272           5 :         struct tevent_req *req = tevent_req_callback_data(
    3273             :                 subreq, struct tevent_req);
    3274           5 :         struct lockread_state *state = tevent_req_data(
    3275             :                 req, struct lockread_state);
    3276           5 :         state->lock_status = cli_lockingx_recv(subreq);
    3277           5 :         TALLOC_FREE(subreq);
    3278           5 :         d_fprintf(stderr,
    3279             :                   "lockingx returned %s\n",
    3280             :                   nt_errstr(state->lock_status));
    3281           5 : }
    3282             : 
    3283           5 : static void lockread_read_andx_done(struct tevent_req *subreq)
    3284             : {
    3285           5 :         struct tevent_req *req = tevent_req_callback_data(
    3286             :                 subreq, struct tevent_req);
    3287           5 :         struct lockread_state *state = tevent_req_data(
    3288             :                 req, struct lockread_state);
    3289           5 :         ssize_t received = -1;
    3290           5 :         uint8_t *rcvbuf = NULL;
    3291             : 
    3292           5 :         state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3293             : 
    3294           5 :         d_fprintf(stderr,
    3295             :                   "read returned %s\n",
    3296             :                   nt_errstr(state->read_status));
    3297             : 
    3298           5 :         if (!NT_STATUS_IS_OK(state->read_status)) {
    3299           4 :                 TALLOC_FREE(subreq);
    3300           4 :                 tevent_req_done(req);
    3301           4 :                 return;
    3302             :         }
    3303             : 
    3304           1 :         if (received > 0) {
    3305           1 :                 state->readbuf = talloc_memdup(state, rcvbuf, received);
    3306           1 :                 TALLOC_FREE(subreq);
    3307           1 :                 if (tevent_req_nomem(state->readbuf, req)) {
    3308           0 :                         return;
    3309             :                 }
    3310             :         }
    3311           1 :         TALLOC_FREE(subreq);
    3312           1 :         tevent_req_done(req);
    3313             : }
    3314             : 
    3315           5 : static NTSTATUS lockread_recv(
    3316             :         struct tevent_req *req,
    3317             :         NTSTATUS *lock_status,
    3318             :         NTSTATUS *read_status,
    3319             :         TALLOC_CTX *mem_ctx,
    3320             :         uint8_t **read_buf)
    3321             : {
    3322           5 :         struct lockread_state *state = tevent_req_data(
    3323             :                 req, struct lockread_state);
    3324           0 :         NTSTATUS status;
    3325             : 
    3326           5 :         if (tevent_req_is_nterror(req, &status)) {
    3327           0 :                 return status;
    3328             :         }
    3329             : 
    3330           5 :         *lock_status = state->lock_status;
    3331           5 :         *read_status = state->read_status;
    3332           5 :         if (state->readbuf != NULL) {
    3333           1 :                 *read_buf = talloc_move(mem_ctx, &state->readbuf);
    3334             :         } else {
    3335           4 :                 *read_buf = NULL;
    3336             :         }
    3337             : 
    3338           5 :         return NT_STATUS_OK;
    3339             : }
    3340             : 
    3341             : struct lock12_state {
    3342             :         uint8_t dummy;
    3343             : };
    3344             : 
    3345             : static void lock12_closed(struct tevent_req *subreq);
    3346             : static void lock12_read(struct tevent_req *subreq);
    3347             : 
    3348           5 : static struct tevent_req *lock12_send(
    3349             :         TALLOC_CTX *mem_ctx,
    3350             :         struct tevent_context *ev,
    3351             :         struct cli_state *cli,
    3352             :         uint16_t fnum1,
    3353             :         uint16_t fnum2)
    3354             : {
    3355           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3356           5 :         struct lock12_state *state = NULL;
    3357             : 
    3358           5 :         req = tevent_req_create(mem_ctx, &state, struct lock12_state);
    3359           5 :         if (req == NULL) {
    3360           0 :                 return NULL;
    3361             :         }
    3362             : 
    3363           5 :         subreq = deferred_close_send(state, ev, 1, cli, fnum1);
    3364           5 :         if (tevent_req_nomem(subreq, req)) {
    3365           0 :                 return tevent_req_post(req, ev);
    3366             :         }
    3367           5 :         tevent_req_set_callback(subreq, lock12_closed, req);
    3368             : 
    3369           5 :         subreq = lockread_send(state, ev, cli, fnum2);
    3370           5 :         if (tevent_req_nomem(subreq, req)) {
    3371           0 :                 return tevent_req_post(req, ev);
    3372             :         }
    3373           5 :         tevent_req_set_callback(subreq, lock12_read, req);
    3374             : 
    3375           5 :         return req;
    3376             : }
    3377             : 
    3378           5 : static void lock12_closed(struct tevent_req *subreq)
    3379             : {
    3380           5 :         struct tevent_req *req = tevent_req_callback_data(
    3381             :                 subreq, struct tevent_req);
    3382           0 :         NTSTATUS status;
    3383             : 
    3384           5 :         status = deferred_close_recv(subreq);
    3385           5 :         TALLOC_FREE(subreq);
    3386           5 :         DBG_DEBUG("close returned %s\n", nt_errstr(status));
    3387           5 :         if (tevent_req_nterror(req, status)) {
    3388           0 :                 return;
    3389             :         }
    3390             : }
    3391             : 
    3392           5 : static void lock12_read(struct tevent_req *subreq)
    3393             : {
    3394           5 :         struct tevent_req *req = tevent_req_callback_data(
    3395             :                 subreq, struct tevent_req);
    3396           5 :         struct lock12_state *state = tevent_req_data(
    3397             :                 req, struct lock12_state);
    3398           0 :         NTSTATUS status, lock_status, read_status;
    3399           5 :         uint8_t *buf = NULL;
    3400             : 
    3401           5 :         status = lockread_recv(
    3402             :                 subreq, &lock_status, &read_status, state, &buf);
    3403           5 :         TALLOC_FREE(subreq);
    3404          10 :         if (tevent_req_nterror(req, status) ||
    3405          10 :             tevent_req_nterror(req, lock_status) ||
    3406           5 :             tevent_req_nterror(req, read_status)) {
    3407           4 :                 return;
    3408             :         }
    3409           1 :         tevent_req_done(req);
    3410             : }
    3411             : 
    3412           5 : static NTSTATUS lock12_recv(struct tevent_req *req)
    3413             : 
    3414             : {
    3415           0 :         NTSTATUS status;
    3416             : 
    3417           5 :         if (tevent_req_is_nterror(req, &status)) {
    3418           4 :                 return status;
    3419             :         }
    3420           1 :         return NT_STATUS_OK;
    3421             : }
    3422             : 
    3423           5 : static bool run_locktest12(int dummy)
    3424             : {
    3425           5 :         struct tevent_context *ev = NULL;
    3426           5 :         struct tevent_req *req = NULL;
    3427           5 :         struct cli_state *cli = NULL;
    3428           5 :         const char fname[] = "\\lockt12.lck";
    3429           0 :         uint16_t fnum1, fnum2;
    3430           5 :         bool ret = false;
    3431           0 :         bool ok;
    3432           5 :         uint8_t data = 1;
    3433           0 :         NTSTATUS status;
    3434             : 
    3435           5 :         printf("starting locktest12\n");
    3436             : 
    3437           5 :         ev = samba_tevent_context_init(NULL);
    3438           5 :         if (ev == NULL) {
    3439           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3440           0 :                 goto done;
    3441             :         }
    3442             : 
    3443           5 :         ok = torture_open_connection(&cli, 0);
    3444           5 :         if (!ok) {
    3445           0 :                 goto done;
    3446             :         }
    3447           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3448             : 
    3449           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3450           5 :         if (!NT_STATUS_IS_OK(status)) {
    3451           0 :                 d_fprintf(stderr,
    3452             :                           "cli_openx failed: %s\n",
    3453             :                           nt_errstr(status));
    3454           0 :                 goto done;
    3455             :         }
    3456             : 
    3457           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3458           5 :         if (!NT_STATUS_IS_OK(status)) {
    3459           0 :                 d_fprintf(stderr,
    3460             :                           "cli_openx failed: %s\n",
    3461             :                           nt_errstr(status));
    3462           0 :                 goto done;
    3463             :         }
    3464             : 
    3465           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3466           5 :         if (!NT_STATUS_IS_OK(status)) {
    3467           0 :                 d_fprintf(stderr,
    3468             :                           "cli_writeall failed: %s\n",
    3469             :                           nt_errstr(status));
    3470           0 :                 goto done;
    3471             :         }
    3472             : 
    3473           5 :         status = cli_locktype(
    3474             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3475           5 :         if (!NT_STATUS_IS_OK(status)) {
    3476           0 :                 d_fprintf(stderr,
    3477             :                           "cli_locktype failed: %s\n",
    3478             :                           nt_errstr(status));
    3479           0 :                 goto done;
    3480             :         }
    3481             : 
    3482           5 :         req = lock12_send(ev, ev, cli, fnum1, fnum2);
    3483           5 :         if (req == NULL) {
    3484           0 :                 d_fprintf(stderr, "lock12_send failed\n");
    3485           0 :                 goto done;
    3486             :         }
    3487             : 
    3488           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3489           5 :         if (!ok) {
    3490           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3491           0 :                 goto done;
    3492             :         }
    3493             : 
    3494           5 :         if (!NT_STATUS_IS_OK(status)) {
    3495           0 :                 d_fprintf(stderr,
    3496             :                           "tevent_req_poll_ntstatus returned %s\n",
    3497             :                           nt_errstr(status));
    3498           0 :                 goto done;
    3499             :         }
    3500             : 
    3501           5 :         status = lock12_recv(req);
    3502           5 :         if (!NT_STATUS_IS_OK(status)) {
    3503           4 :                 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
    3504           4 :                 goto done;
    3505             :         }
    3506             : 
    3507           1 :         ret = true;
    3508           5 : done:
    3509           5 :         if (cli != NULL) {
    3510           5 :                 torture_close_connection(cli);
    3511             :         }
    3512           5 :         return ret;
    3513             : }
    3514             : 
    3515             : struct lock_ntcancel_state {
    3516             :         struct timeval start;
    3517             :         struct smb1_lock_element lck;
    3518             :         struct tevent_req *subreq;
    3519             : };
    3520             : 
    3521             : static void lock_ntcancel_waited(struct tevent_req *subreq);
    3522             : static void lock_ntcancel_done(struct tevent_req *subreq);
    3523             : 
    3524           5 : static struct tevent_req *lock_ntcancel_send(
    3525             :         TALLOC_CTX *mem_ctx,
    3526             :         struct tevent_context *ev,
    3527             :         struct cli_state *cli,
    3528             :         uint16_t fnum)
    3529             : {
    3530           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3531           5 :         struct lock_ntcancel_state *state = NULL;
    3532             : 
    3533           5 :         req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
    3534           5 :         if (req == NULL) {
    3535           0 :                 return NULL;
    3536             :         }
    3537          10 :         state->lck = (struct smb1_lock_element) {
    3538           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3539             :         };
    3540           5 :         state->start = timeval_current();
    3541             : 
    3542          10 :         state->subreq = cli_lockingx_send(
    3543             :                 state,                          /* mem_ctx */
    3544             :                 ev,                             /* tevent_context */
    3545             :                 cli,                            /* cli */
    3546             :                 fnum,                           /* fnum */
    3547             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3548             :                 0,                              /* newoplocklevel */
    3549             :                 10000,                          /* timeout */
    3550             :                 0,                              /* num_unlocks */
    3551             :                 NULL,                           /* unlocks */
    3552             :                 1,                              /* num_locks */
    3553           5 :                 &state->lck);                    /* locks */
    3554           5 :         if (tevent_req_nomem(state->subreq, req)) {
    3555           0 :                 return tevent_req_post(req, ev);
    3556             :         }
    3557           5 :         tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
    3558             : 
    3559           5 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
    3560           5 :         if (tevent_req_nomem(subreq, req)) {
    3561           0 :                 return tevent_req_post(req, ev);
    3562             :         }
    3563           5 :         tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
    3564           5 :         return req;
    3565             : }
    3566             : 
    3567           5 : static void lock_ntcancel_waited(struct tevent_req *subreq)
    3568             : {
    3569           5 :         struct tevent_req *req = tevent_req_callback_data(
    3570             :                 subreq, struct tevent_req);
    3571           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3572             :                 req, struct lock_ntcancel_state);
    3573           0 :         bool ok;
    3574             : 
    3575           5 :         ok = tevent_wakeup_recv(subreq);
    3576           5 :         TALLOC_FREE(subreq);
    3577           5 :         if (!ok) {
    3578           0 :                 tevent_req_oom(req);
    3579           0 :                 return;
    3580             :         }
    3581             : 
    3582           5 :         ok = tevent_req_cancel(state->subreq);
    3583           5 :         if (!ok) {
    3584           0 :                 d_fprintf(stderr, "Could not cancel subreq\n");
    3585           0 :                 tevent_req_oom(req);
    3586           0 :                 return;
    3587             :         }
    3588             : }
    3589             : 
    3590           5 : static void lock_ntcancel_done(struct tevent_req *subreq)
    3591             : {
    3592           5 :         struct tevent_req *req = tevent_req_callback_data(
    3593             :                 subreq, struct tevent_req);
    3594           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3595             :                 req, struct lock_ntcancel_state);
    3596           0 :         NTSTATUS status;
    3597           0 :         double elapsed;
    3598             : 
    3599           5 :         status = cli_lockingx_recv(subreq);
    3600           5 :         TALLOC_FREE(subreq);
    3601             : 
    3602           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3603           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3604           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3605           0 :                 return;
    3606             :         }
    3607             : 
    3608           5 :         elapsed = timeval_elapsed(&state->start);
    3609             : 
    3610           5 :         if (elapsed > 3) {
    3611           0 :                 d_printf("cli_lockingx was too slow, cancel did not work\n");
    3612           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3613           0 :                 return;
    3614             :         }
    3615             : 
    3616           5 :         tevent_req_done(req);
    3617             : }
    3618             : 
    3619           5 : static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
    3620             : {
    3621           5 :         return tevent_req_simple_recv_ntstatus(req);
    3622             : }
    3623             : 
    3624           5 : static bool run_locktest13(int dummy)
    3625             : {
    3626           5 :         struct tevent_context *ev = NULL;
    3627           5 :         struct tevent_req *req = NULL;
    3628           5 :         struct cli_state *cli = NULL;
    3629           5 :         const char fname[] = "\\lockt13.lck";
    3630           0 :         uint16_t fnum1, fnum2;
    3631           5 :         bool ret = false;
    3632           0 :         bool ok;
    3633           5 :         uint8_t data = 1;
    3634           0 :         NTSTATUS status;
    3635             : 
    3636           5 :         printf("starting locktest13\n");
    3637             : 
    3638           5 :         ev = samba_tevent_context_init(NULL);
    3639           5 :         if (ev == NULL) {
    3640           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3641           0 :                 goto done;
    3642             :         }
    3643             : 
    3644           5 :         ok = torture_open_connection(&cli, 0);
    3645           5 :         if (!ok) {
    3646           0 :                 goto done;
    3647             :         }
    3648           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3649             : 
    3650           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3651           5 :         if (!NT_STATUS_IS_OK(status)) {
    3652           0 :                 d_fprintf(stderr,
    3653             :                           "cli_openx failed: %s\n",
    3654             :                           nt_errstr(status));
    3655           0 :                 goto done;
    3656             :         }
    3657             : 
    3658           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3659           5 :         if (!NT_STATUS_IS_OK(status)) {
    3660           0 :                 d_fprintf(stderr,
    3661             :                           "cli_openx failed: %s\n",
    3662             :                           nt_errstr(status));
    3663           0 :                 goto done;
    3664             :         }
    3665             : 
    3666           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3667           5 :         if (!NT_STATUS_IS_OK(status)) {
    3668           0 :                 d_fprintf(stderr,
    3669             :                           "cli_writeall failed: %s\n",
    3670             :                           nt_errstr(status));
    3671           0 :                 goto done;
    3672             :         }
    3673             : 
    3674           5 :         status = cli_locktype(
    3675             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3676           5 :         if (!NT_STATUS_IS_OK(status)) {
    3677           0 :                 d_fprintf(stderr,
    3678             :                           "cli_locktype failed: %s\n",
    3679             :                           nt_errstr(status));
    3680           0 :                 goto done;
    3681             :         }
    3682             : 
    3683           5 :         req = lock_ntcancel_send(ev, ev, cli, fnum2);
    3684           5 :         if (req == NULL) {
    3685           0 :                 d_fprintf(stderr, "lock_ntcancel_send failed\n");
    3686           0 :                 goto done;
    3687             :         }
    3688             : 
    3689           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3690           5 :         if (!ok) {
    3691           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3692           0 :                 goto done;
    3693             :         }
    3694             : 
    3695           5 :         if (!NT_STATUS_IS_OK(status)) {
    3696           0 :                 d_fprintf(stderr,
    3697             :                           "tevent_req_poll_ntstatus returned %s\n",
    3698             :                           nt_errstr(status));
    3699           0 :                 goto done;
    3700             :         }
    3701             : 
    3702           5 :         status = lock_ntcancel_recv(req);
    3703           5 :         if (!NT_STATUS_IS_OK(status)) {
    3704           0 :                 d_fprintf(stderr,
    3705             :                           "lock_ntcancel returned %s\n",
    3706             :                           nt_errstr(status));
    3707           0 :                 goto done;
    3708             :         }
    3709             : 
    3710           5 :         ret = true;
    3711           5 : done:
    3712           5 :         if (cli != NULL) {
    3713           5 :                 torture_close_connection(cli);
    3714             :         }
    3715           5 :         return ret;
    3716             : }
    3717             : 
    3718             : /*
    3719             : test whether fnums and tids open on one VC are available on another (a major
    3720             : security hole)
    3721             : */
    3722           5 : static bool run_fdpasstest(int dummy)
    3723             : {
    3724           0 :         struct cli_state *cli1, *cli2;
    3725           5 :         const char *fname = "\\fdpass.tst";
    3726           0 :         uint16_t fnum1;
    3727           0 :         char buf[1024];
    3728           0 :         NTSTATUS status;
    3729             : 
    3730           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    3731           0 :                 return False;
    3732             :         }
    3733           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3734           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    3735             : 
    3736           5 :         printf("starting fdpasstest\n");
    3737             : 
    3738           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3739             : 
    3740           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    3741             :                           &fnum1);
    3742           5 :         if (!NT_STATUS_IS_OK(status)) {
    3743           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3744           0 :                 return False;
    3745             :         }
    3746             : 
    3747           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
    3748             :                               13, NULL);
    3749           5 :         if (!NT_STATUS_IS_OK(status)) {
    3750           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3751           0 :                 return False;
    3752             :         }
    3753             : 
    3754           5 :         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
    3755           5 :         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
    3756           5 :         cli_setpid(cli2, cli_getpid(cli1));
    3757             : 
    3758           5 :         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
    3759           0 :                 printf("read succeeded! nasty security hole [%s]\n", buf);
    3760           0 :                 return false;
    3761             :         }
    3762             : 
    3763           5 :         cli_close(cli1, fnum1);
    3764           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3765             : 
    3766           5 :         torture_close_connection(cli1);
    3767           5 :         torture_close_connection(cli2);
    3768             : 
    3769           5 :         printf("finished fdpasstest\n");
    3770           5 :         return True;
    3771             : }
    3772             : 
    3773           5 : static bool run_fdsesstest(int dummy)
    3774             : {
    3775           0 :         struct cli_state *cli;
    3776           0 :         uint16_t new_vuid;
    3777           0 :         uint16_t saved_vuid;
    3778           0 :         uint32_t new_cnum;
    3779           0 :         uint32_t saved_cnum;
    3780           5 :         const char *fname = "\\fdsess.tst";
    3781           5 :         const char *fname1 = "\\fdsess1.tst";
    3782           0 :         uint16_t fnum1;
    3783           0 :         uint16_t fnum2;
    3784           0 :         char buf[1024];
    3785           5 :         bool ret = True;
    3786           0 :         NTSTATUS status;
    3787             : 
    3788           5 :         if (!torture_open_connection(&cli, 0))
    3789           0 :                 return False;
    3790           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3791             : 
    3792           5 :         if (!torture_cli_session_setup2(cli, &new_vuid))
    3793           0 :                 return False;
    3794             : 
    3795           5 :         saved_cnum = cli_state_get_tid(cli);
    3796           5 :         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
    3797           0 :                 return False;
    3798           5 :         new_cnum = cli_state_get_tid(cli);
    3799           5 :         cli_state_set_tid(cli, saved_cnum);
    3800             : 
    3801           5 :         printf("starting fdsesstest\n");
    3802             : 
    3803           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3804           5 :         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3805             : 
    3806           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    3807           5 :         if (!NT_STATUS_IS_OK(status)) {
    3808           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3809           0 :                 return False;
    3810             :         }
    3811             : 
    3812           5 :         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
    3813             :                               NULL);
    3814           5 :         if (!NT_STATUS_IS_OK(status)) {
    3815           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3816           0 :                 return False;
    3817             :         }
    3818             : 
    3819           5 :         saved_vuid = cli_state_get_uid(cli);
    3820           5 :         cli_state_set_uid(cli, new_vuid);
    3821             : 
    3822           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3823           0 :                 printf("read succeeded with different vuid! "
    3824             :                        "nasty security hole [%s]\n", buf);
    3825           0 :                 ret = false;
    3826             :         }
    3827             :         /* Try to open a file with different vuid, samba cnum. */
    3828           5 :         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
    3829           5 :                 printf("create with different vuid, same cnum succeeded.\n");
    3830           5 :                 cli_close(cli, fnum2);
    3831           5 :                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3832             :         } else {
    3833           0 :                 printf("create with different vuid, same cnum failed.\n");
    3834           0 :                 printf("This will cause problems with service clients.\n");
    3835           0 :                 ret = False;
    3836             :         }
    3837             : 
    3838           5 :         cli_state_set_uid(cli, saved_vuid);
    3839             : 
    3840             :         /* Try with same vuid, different cnum. */
    3841           5 :         cli_state_set_tid(cli, new_cnum);
    3842             : 
    3843           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3844           0 :                 printf("read succeeded with different cnum![%s]\n", buf);
    3845           0 :                 ret = false;
    3846             :         }
    3847             : 
    3848           5 :         cli_state_set_tid(cli, saved_cnum);
    3849           5 :         cli_close(cli, fnum1);
    3850           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3851             : 
    3852           5 :         torture_close_connection(cli);
    3853             : 
    3854           5 :         printf("finished fdsesstest\n");
    3855           5 :         return ret;
    3856             : }
    3857             : 
    3858             : /*
    3859             :   This test checks that 
    3860             : 
    3861             :   1) the server does not allow an unlink on a file that is open
    3862             : */
    3863           5 : static bool run_unlinktest(int dummy)
    3864             : {
    3865           0 :         struct cli_state *cli;
    3866           5 :         const char *fname = "\\unlink.tst";
    3867           0 :         uint16_t fnum;
    3868           5 :         bool correct = True;
    3869           0 :         NTSTATUS status;
    3870             : 
    3871           5 :         if (!torture_open_connection(&cli, 0)) {
    3872           0 :                 return False;
    3873             :         }
    3874             : 
    3875           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3876             : 
    3877           5 :         printf("starting unlink test\n");
    3878             : 
    3879           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3880             : 
    3881           5 :         cli_setpid(cli, 1);
    3882             : 
    3883           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    3884           5 :         if (!NT_STATUS_IS_OK(status)) {
    3885           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3886           0 :                 return False;
    3887             :         }
    3888             : 
    3889           5 :         status = cli_unlink(cli, fname,
    3890             :                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3891           5 :         if (NT_STATUS_IS_OK(status)) {
    3892           0 :                 printf("error: server allowed unlink on an open file\n");
    3893           0 :                 correct = False;
    3894             :         } else {
    3895           5 :                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
    3896           5 :                                       NT_STATUS_SHARING_VIOLATION);
    3897             :         }
    3898             : 
    3899           5 :         cli_close(cli, fnum);
    3900           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3901             : 
    3902           5 :         if (!torture_close_connection(cli)) {
    3903           0 :                 correct = False;
    3904             :         }
    3905             : 
    3906           5 :         printf("unlink test finished\n");
    3907             : 
    3908           5 :         return correct;
    3909             : }
    3910             : 
    3911             : 
    3912             : /*
    3913             : test how many open files this server supports on the one socket
    3914             : */
    3915           0 : static bool run_maxfidtest(int dummy)
    3916             : {
    3917           0 :         struct cli_state *cli;
    3918           0 :         fstring fname;
    3919           0 :         uint16_t fnums[0x11000];
    3920           0 :         int i;
    3921           0 :         int retries=4;
    3922           0 :         bool correct = True;
    3923           0 :         NTSTATUS status;
    3924             : 
    3925           0 :         cli = current_cli;
    3926             : 
    3927           0 :         if (retries <= 0) {
    3928           0 :                 printf("failed to connect\n");
    3929           0 :                 return False;
    3930             :         }
    3931             : 
    3932           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3933             : 
    3934           0 :         for (i=0; i<0x11000; i++) {
    3935           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3936           0 :                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
    3937             :                                   &fnums[i]);
    3938           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3939           0 :                         printf("open of %s failed (%s)\n", 
    3940             :                                fname, nt_errstr(status));
    3941           0 :                         printf("maximum fnum is %d\n", i);
    3942           0 :                         break;
    3943             :                 }
    3944           0 :                 printf("%6d\r", i);
    3945             :         }
    3946           0 :         printf("%6d\n", i);
    3947           0 :         i--;
    3948             : 
    3949           0 :         printf("cleaning up\n");
    3950           0 :         for (;i>=0;i--) {
    3951           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3952           0 :                 cli_close(cli, fnums[i]);
    3953             : 
    3954           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3955           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3956           0 :                         printf("unlink of %s failed (%s)\n", 
    3957             :                                fname, nt_errstr(status));
    3958           0 :                         correct = False;
    3959             :                 }
    3960           0 :                 printf("%6d\r", i);
    3961             :         }
    3962           0 :         printf("%6d\n", 0);
    3963             : 
    3964           0 :         printf("maxfid test finished\n");
    3965           0 :         if (!torture_close_connection(cli)) {
    3966           0 :                 correct = False;
    3967             :         }
    3968           0 :         return correct;
    3969             : }
    3970             : 
    3971             : /* generate a random buffer */
    3972           0 : static void rand_buf(char *buf, int len)
    3973             : {
    3974           0 :         while (len--) {
    3975           0 :                 *buf = (char)sys_random();
    3976           0 :                 buf++;
    3977             :         }
    3978           0 : }
    3979             : 
    3980             : /* send smb negprot commands, not reading the response */
    3981           0 : static bool run_negprot_nowait(int dummy)
    3982             : {
    3983           0 :         struct tevent_context *ev;
    3984           0 :         int i;
    3985           0 :         struct cli_state *cli;
    3986           0 :         bool correct = True;
    3987             : 
    3988           0 :         printf("starting negprot nowait test\n");
    3989             : 
    3990           0 :         ev = samba_tevent_context_init(talloc_tos());
    3991           0 :         if (ev == NULL) {
    3992           0 :                 return false;
    3993             :         }
    3994             : 
    3995           0 :         if (!(cli = open_nbt_connection())) {
    3996           0 :                 TALLOC_FREE(ev);
    3997           0 :                 return False;
    3998             :         }
    3999             : 
    4000           0 :         for (i=0;i<50000;i++) {
    4001           0 :                 struct tevent_req *req;
    4002             : 
    4003           0 :                 req = smbXcli_negprot_send(
    4004             :                         ev,
    4005             :                         ev,
    4006             :                         cli->conn,
    4007           0 :                         cli->timeout,
    4008             :                         PROTOCOL_CORE,
    4009             :                         PROTOCOL_NT1,
    4010             :                         0,
    4011             :                         NULL);
    4012           0 :                 if (req == NULL) {
    4013           0 :                         TALLOC_FREE(ev);
    4014           0 :                         return false;
    4015             :                 }
    4016           0 :                 if (!tevent_req_poll(req, ev)) {
    4017           0 :                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
    4018           0 :                                   strerror(errno));
    4019           0 :                         TALLOC_FREE(ev);
    4020           0 :                         return false;
    4021             :                 }
    4022           0 :                 TALLOC_FREE(req);
    4023             :         }
    4024             : 
    4025           0 :         if (torture_close_connection(cli)) {
    4026           0 :                 correct = False;
    4027             :         }
    4028             : 
    4029           0 :         printf("finished negprot nowait test\n");
    4030             : 
    4031           0 :         return correct;
    4032             : }
    4033             : 
    4034             : /* send smb negprot commands, not reading the response */
    4035           4 : static bool run_bad_nbt_session(int dummy)
    4036             : {
    4037           0 :         struct nmb_name called, calling;
    4038           0 :         struct sockaddr_storage ss;
    4039           0 :         NTSTATUS status;
    4040           0 :         int fd;
    4041           0 :         bool ret;
    4042             : 
    4043           4 :         printf("starting bad nbt session test\n");
    4044             : 
    4045           4 :         make_nmb_name(&calling, myname, 0x0);
    4046           4 :         make_nmb_name(&called , host, 0x20);
    4047             : 
    4048           4 :         if (!resolve_name(host, &ss, 0x20, true)) {
    4049           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
    4050           0 :                 return false;
    4051             :         }
    4052             : 
    4053           4 :         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
    4054           4 :         if (!NT_STATUS_IS_OK(status)) {
    4055           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4056             :                           nt_errstr(status));
    4057           0 :                 return false;
    4058             :         }
    4059             : 
    4060           4 :         ret = cli_bad_session_request(fd, &calling, &called);
    4061           4 :         close(fd);
    4062           4 :         if (!ret) {
    4063           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4064             :                           nt_errstr(status));
    4065           0 :                 return false;
    4066             :         }
    4067             : 
    4068           4 :         printf("finished bad nbt session test\n");
    4069           4 :         return true;
    4070             : }
    4071             : 
    4072             : /* send random IPC commands */
    4073           0 : static bool run_randomipc(int dummy)
    4074             : {
    4075           0 :         char *rparam = NULL;
    4076           0 :         char *rdata = NULL;
    4077           0 :         unsigned int rdrcnt,rprcnt;
    4078           0 :         char param[1024];
    4079           0 :         int api, param_len, i;
    4080           0 :         struct cli_state *cli;
    4081           0 :         bool correct = True;
    4082           0 :         int count = 50000;
    4083             : 
    4084           0 :         printf("starting random ipc test\n");
    4085             : 
    4086           0 :         if (!torture_open_connection(&cli, 0)) {
    4087           0 :                 return False;
    4088             :         }
    4089             : 
    4090           0 :         for (i=0;i<count;i++) {
    4091           0 :                 api = sys_random() % 500;
    4092           0 :                 param_len = (sys_random() % 64);
    4093             : 
    4094           0 :                 rand_buf(param, param_len);
    4095             : 
    4096           0 :                 SSVAL(param,0,api); 
    4097             : 
    4098           0 :                 cli_api(cli, 
    4099             :                         param, param_len, 8,  
    4100             :                         NULL, 0, CLI_BUFFER_SIZE,
    4101             :                         &rparam, &rprcnt,     
    4102             :                         &rdata, &rdrcnt);
    4103           0 :                 if (i % 100 == 0) {
    4104           0 :                         printf("%d/%d\r", i,count);
    4105             :                 }
    4106             :         }
    4107           0 :         printf("%d/%d\n", i, count);
    4108             : 
    4109           0 :         if (!torture_close_connection(cli)) {
    4110           0 :                 correct = False;
    4111             :         }
    4112             : 
    4113           0 :         SAFE_FREE(rparam);
    4114           0 :         SAFE_FREE(rdata);
    4115             : 
    4116           0 :         printf("finished random ipc test\n");
    4117             : 
    4118           0 :         return correct;
    4119             : }
    4120             : 
    4121             : 
    4122             : 
    4123           8 : static void browse_callback(const char *sname, uint32_t stype,
    4124             :                             const char *comment, void *state)
    4125             : {
    4126           8 :         printf("\t%20.20s %08x %s\n", sname, stype, comment);
    4127           8 : }
    4128             : 
    4129             : 
    4130             : 
    4131             : /*
    4132             :   This test checks the browse list code
    4133             : 
    4134             : */
    4135           5 : static bool run_browsetest(int dummy)
    4136             : {
    4137           0 :         static struct cli_state *cli;
    4138           5 :         bool correct = True;
    4139             : 
    4140           5 :         printf("starting browse test\n");
    4141             : 
    4142           5 :         if (!torture_open_connection(&cli, 0)) {
    4143           0 :                 return False;
    4144             :         }
    4145             : 
    4146           5 :         printf("domain list:\n");
    4147           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    4148             :                           SV_TYPE_DOMAIN_ENUM,
    4149             :                           browse_callback, NULL);
    4150             : 
    4151           5 :         printf("machine list:\n");
    4152           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    4153             :                           SV_TYPE_ALL,
    4154             :                           browse_callback, NULL);
    4155             : 
    4156           5 :         if (!torture_close_connection(cli)) {
    4157           0 :                 correct = False;
    4158             :         }
    4159             : 
    4160           5 :         printf("browse test finished\n");
    4161             : 
    4162           5 :         return correct;
    4163             : 
    4164             : }
    4165             : 
    4166          20 : static bool check_attributes(struct cli_state *cli,
    4167             :                                 const char *fname,
    4168             :                                 uint32_t expected_attrs)
    4169             : {
    4170          20 :         uint32_t attrs = 0;
    4171          20 :         NTSTATUS status = cli_getatr(cli,
    4172             :                                 fname,
    4173             :                                 &attrs,
    4174             :                                 NULL,
    4175             :                                 NULL);
    4176          20 :         if (!NT_STATUS_IS_OK(status)) {
    4177           0 :                 printf("cli_getatr failed with %s\n",
    4178             :                         nt_errstr(status));
    4179           0 :                 return false;
    4180             :         }
    4181          20 :         if (attrs != expected_attrs) {
    4182           0 :                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
    4183             :                         (unsigned int)attrs,
    4184             :                         (unsigned int)expected_attrs);
    4185           0 :                 return false;
    4186             :         }
    4187          20 :         return true;
    4188             : }
    4189             : 
    4190             : /*
    4191             :   This checks how the getatr calls works
    4192             : */
    4193           5 : static bool run_attrtest(int dummy)
    4194             : {
    4195           0 :         struct cli_state *cli;
    4196           0 :         uint16_t fnum;
    4197           0 :         time_t t, t2;
    4198           5 :         const char *fname = "\\attrib123456789.tst";
    4199           5 :         bool correct = True;
    4200           0 :         NTSTATUS status;
    4201             : 
    4202           5 :         printf("starting attrib test\n");
    4203             : 
    4204           5 :         if (!torture_open_connection(&cli, 0)) {
    4205           0 :                 return False;
    4206             :         }
    4207             : 
    4208             :         /* Ensure we can't unlink with out-of-range (unknown) attribute. */
    4209           5 :         status = cli_unlink(cli, fname, 0x20000);
    4210           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4211           0 :                 correct = false;
    4212           0 :                 goto out;
    4213             :         }
    4214             : 
    4215           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4216           5 :         cli_openx(cli, fname, 
    4217             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4218           5 :         cli_close(cli, fnum);
    4219             : 
    4220           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4221           5 :         if (!NT_STATUS_IS_OK(status)) {
    4222           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4223           0 :                 correct = False;
    4224             :         }
    4225             : 
    4226           5 :         if (labs(t - time(NULL)) > 60*60*24*10) {
    4227           0 :                 printf("ERROR: SMBgetatr bug. time is %s",
    4228             :                        ctime(&t));
    4229           0 :                 t = time(NULL);
    4230           0 :                 correct = True;
    4231             :         }
    4232             : 
    4233           5 :         t2 = t-60*60*24; /* 1 day ago */
    4234             : 
    4235             :         /* Ensure we can't set with out-of-range (unknown) attribute. */
    4236           5 :         status = cli_setatr(cli, fname, 0x20000, t2);
    4237           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4238           0 :                 correct = false;
    4239           0 :                 goto out;
    4240             :         }
    4241             : 
    4242           5 :         status = cli_setatr(cli, fname, 0, t2);
    4243           5 :         if (!NT_STATUS_IS_OK(status)) {
    4244           0 :                 printf("setatr failed (%s)\n", nt_errstr(status));
    4245           0 :                 correct = True;
    4246             :         }
    4247             : 
    4248           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4249           5 :         if (!NT_STATUS_IS_OK(status)) {
    4250           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4251           0 :                 correct = True;
    4252             :         }
    4253             : 
    4254           5 :         if (t != t2) {
    4255           0 :                 printf("ERROR: getatr/setatr bug. times are\n%s",
    4256             :                        ctime(&t));
    4257           0 :                 printf("%s", ctime(&t2));
    4258           0 :                 correct = True;
    4259             :         }
    4260             : 
    4261           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4262             : 
    4263             :         /* Check cli_setpathinfo_ext() */
    4264             :         /* Re-create the file. */
    4265           5 :         status = cli_openx(cli, fname,
    4266             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4267           5 :         if (!NT_STATUS_IS_OK(status)) {
    4268           0 :                 printf("Failed to recreate %s (%s)\n",
    4269             :                         fname, nt_errstr(status));
    4270           0 :                 correct = false;
    4271             :         }
    4272           5 :         cli_close(cli, fnum);
    4273             : 
    4274           5 :         status = cli_setpathinfo_ext(
    4275             :                 cli,
    4276             :                 fname,
    4277           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4278           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4279           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4280           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4281             :                 FILE_ATTRIBUTE_SYSTEM |
    4282             :                 FILE_ATTRIBUTE_HIDDEN |
    4283             :                 FILE_ATTRIBUTE_READONLY);
    4284           5 :         if (!NT_STATUS_IS_OK(status)) {
    4285           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4286             :                         nt_errstr(status));
    4287           0 :                 correct = false;
    4288             :         }
    4289             : 
    4290             :         /* Check attributes are correct. */
    4291           5 :         correct = check_attributes(cli,
    4292             :                         fname,
    4293             :                         FILE_ATTRIBUTE_SYSTEM |
    4294             :                         FILE_ATTRIBUTE_HIDDEN |
    4295             :                         FILE_ATTRIBUTE_READONLY);
    4296           5 :         if (correct == false) {
    4297           0 :                 goto out;
    4298             :         }
    4299             : 
    4300             :         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
    4301           5 :         status = cli_setpathinfo_ext(
    4302             :                 cli,
    4303             :                 fname,
    4304           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4305           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4306           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4307           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4308             :                 FILE_ATTRIBUTE_NORMAL);
    4309           5 :         if (!NT_STATUS_IS_OK(status)) {
    4310           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4311             :                         nt_errstr(status));
    4312           0 :                 correct = false;
    4313             :         }
    4314             : 
    4315             :         /* Check attributes are correct. */
    4316           5 :         correct = check_attributes(cli,
    4317             :                         fname,
    4318             :                         FILE_ATTRIBUTE_SYSTEM |
    4319             :                         FILE_ATTRIBUTE_HIDDEN |
    4320             :                         FILE_ATTRIBUTE_READONLY);
    4321           5 :         if (correct == false) {
    4322           0 :                 goto out;
    4323             :         }
    4324             : 
    4325             :         /* Setting to (uint16_t)-1 should also be ignored. */
    4326           5 :         status = cli_setpathinfo_ext(
    4327             :                 cli,
    4328             :                 fname,
    4329           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4330           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4331           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4332           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4333             :                 (uint32_t)-1);
    4334           5 :         if (!NT_STATUS_IS_OK(status)) {
    4335           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4336             :                         nt_errstr(status));
    4337           0 :                 correct = false;
    4338             :         }
    4339             : 
    4340             :         /* Check attributes are correct. */
    4341           5 :         correct = check_attributes(cli,
    4342             :                         fname,
    4343             :                         FILE_ATTRIBUTE_SYSTEM |
    4344             :                         FILE_ATTRIBUTE_HIDDEN |
    4345             :                         FILE_ATTRIBUTE_READONLY);
    4346           5 :         if (correct == false) {
    4347           0 :                 goto out;
    4348             :         }
    4349             : 
    4350             :         /* Setting to 0 should clear them all. */
    4351           5 :         status = cli_setpathinfo_ext(
    4352             :                 cli,
    4353             :                 fname,
    4354           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4355           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4356           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4357           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4358             :                 0);
    4359           5 :         if (!NT_STATUS_IS_OK(status)) {
    4360           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4361             :                         nt_errstr(status));
    4362           0 :                 correct = false;
    4363             :         }
    4364             : 
    4365             :         /* Check attributes are correct. */
    4366           5 :         correct = check_attributes(cli,
    4367             :                         fname,
    4368             :                         FILE_ATTRIBUTE_NORMAL);
    4369           5 :         if (correct == false) {
    4370           0 :                 goto out;
    4371             :         }
    4372             : 
    4373           5 :   out:
    4374             : 
    4375           5 :         cli_unlink(cli,
    4376             :                 fname,
    4377             :                 FILE_ATTRIBUTE_SYSTEM |
    4378             :                 FILE_ATTRIBUTE_HIDDEN|
    4379             :                 FILE_ATTRIBUTE_READONLY);
    4380             : 
    4381           5 :         if (!torture_close_connection(cli)) {
    4382           0 :                 correct = False;
    4383             :         }
    4384             : 
    4385           5 :         printf("attrib test finished\n");
    4386             : 
    4387           5 :         return correct;
    4388             : }
    4389             : 
    4390           5 : static NTSTATUS cli_qfilename(
    4391             :         struct cli_state *cli,
    4392             :         uint16_t fnum,
    4393             :         TALLOC_CTX *mem_ctx,
    4394             :         char **_name)
    4395             : {
    4396           0 :         uint16_t recv_flags2;
    4397           0 :         uint8_t *rdata;
    4398           0 :         uint32_t num_rdata;
    4399           0 :         NTSTATUS status;
    4400           5 :         char *name = NULL;
    4401           0 :         uint32_t namelen;
    4402             : 
    4403           5 :         status = cli_qfileinfo(talloc_tos(), cli, fnum,
    4404             :                                SMB_QUERY_FILE_NAME_INFO,
    4405             :                                4, CLI_BUFFER_SIZE, &recv_flags2,
    4406             :                                &rdata, &num_rdata);
    4407           5 :         if (!NT_STATUS_IS_OK(status)) {
    4408           0 :                 return status;
    4409             :         }
    4410             : 
    4411           5 :         namelen = IVAL(rdata, 0);
    4412           5 :         if (namelen > (num_rdata - 4)) {
    4413           0 :                 TALLOC_FREE(rdata);
    4414           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    4415             :         }
    4416             : 
    4417           5 :         pull_string_talloc(mem_ctx,
    4418             :                            (const char *)rdata,
    4419             :                            recv_flags2,
    4420             :                            &name,
    4421           5 :                            rdata + 4,
    4422             :                            namelen,
    4423             :                            STR_UNICODE);
    4424           5 :         if (name == NULL) {
    4425           0 :                 status = map_nt_error_from_unix(errno);
    4426           0 :                 TALLOC_FREE(rdata);
    4427           0 :                 return status;
    4428             :         }
    4429             : 
    4430           5 :         *_name = name;
    4431           5 :         TALLOC_FREE(rdata);
    4432           5 :         return NT_STATUS_OK;
    4433             : }
    4434             : 
    4435             : /*
    4436             :   This checks a couple of trans2 calls
    4437             : */
    4438           5 : static bool run_trans2test(int dummy)
    4439             : {
    4440           0 :         struct cli_state *cli;
    4441           0 :         uint16_t fnum;
    4442           0 :         off_t size;
    4443           0 :         time_t c_time, a_time, m_time;
    4444           0 :         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
    4445           5 :         const char *fname = "\\trans2.tst";
    4446           5 :         const char *dname = "\\trans2";
    4447           5 :         const char *fname2 = "\\trans2\\trans2.tst";
    4448           5 :         char *pname = NULL;
    4449           5 :         bool correct = True;
    4450           0 :         NTSTATUS status;
    4451           0 :         uint32_t fs_attr;
    4452           0 :         uint64_t ino;
    4453             : 
    4454           5 :         printf("starting trans2 test\n");
    4455             : 
    4456           5 :         if (!torture_open_connection(&cli, 0)) {
    4457           0 :                 return False;
    4458             :         }
    4459             : 
    4460           5 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4461             :                 /* Ensure ino is zero, SMB2 gets a real one. */
    4462           0 :                 ino = 0;
    4463             :         } else {
    4464             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
    4465           5 :                 ino = (uint64_t)-1;
    4466             :         }
    4467             : 
    4468           5 :         status = cli_get_fs_attr_info(cli, &fs_attr);
    4469           5 :         if (!NT_STATUS_IS_OK(status)) {
    4470           0 :                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
    4471             :                        nt_errstr(status));
    4472           0 :                 correct = false;
    4473             :         }
    4474             : 
    4475           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4476           5 :         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4477           5 :         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
    4478             :                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
    4479           5 :         if (!NT_STATUS_IS_OK(status)) {
    4480           0 :                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
    4481           0 :                 correct = False;
    4482             :         }
    4483             : 
    4484           5 :         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
    4485           5 :         if (!NT_STATUS_IS_OK(status)) {
    4486           0 :                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
    4487           0 :                 correct = False;
    4488             :         }
    4489           5 :         else if (strcmp(pname, fname)) {
    4490           0 :                 printf("qfilename gave different name? [%s] [%s]\n",
    4491             :                        fname, pname);
    4492           0 :                 correct = False;
    4493             :         }
    4494             : 
    4495           5 :         cli_close(cli, fnum);
    4496             : 
    4497           5 :         sleep(2);
    4498             : 
    4499           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4500           5 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
    4501             :                           &fnum);
    4502           5 :         if (!NT_STATUS_IS_OK(status)) {
    4503           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4504           0 :                 return False;
    4505             :         }
    4506           5 :         cli_close(cli, fnum);
    4507             : 
    4508           5 :         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
    4509             :                                 NULL);
    4510           5 :         if (!NT_STATUS_IS_OK(status)) {
    4511           0 :                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
    4512           0 :                 correct = False;
    4513             :         } else {
    4514           5 :                 time_t t = time(NULL);
    4515             : 
    4516           5 :                 if (c_time != m_time) {
    4517           0 :                         printf("create time=%s", ctime(&c_time));
    4518           0 :                         printf("modify time=%s", ctime(&m_time));
    4519           0 :                         printf("This system appears to have sticky create times\n");
    4520             :                 }
    4521           5 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
    4522           0 :                         printf("access time=%s", ctime(&a_time));
    4523           0 :                         printf("This system appears to set a midnight access time\n");
    4524           0 :                         correct = False;
    4525             :                 }
    4526             : 
    4527           5 :                 if (labs(m_time - t) > 60*60*24*7) {
    4528           0 :                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
    4529           0 :                         correct = False;
    4530             :                 }
    4531             :         }
    4532             : 
    4533             : 
    4534           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4535           5 :         cli_openx(cli, fname, 
    4536             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4537           5 :         cli_close(cli, fnum);
    4538           5 :         status = cli_qpathinfo2(cli,
    4539             :                                 fname,
    4540             :                                 &c_time_ts,
    4541             :                                 &a_time_ts,
    4542             :                                 &w_time_ts,
    4543             :                                 &m_time_ts,
    4544             :                                 &size,
    4545             :                                 NULL,
    4546             :                                 &ino,
    4547             :                                 NULL);
    4548           5 :         if (!NT_STATUS_IS_OK(status)) {
    4549           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4550           0 :                 correct = False;
    4551             :         } else {
    4552           5 :                 if (w_time_ts.tv_sec < 60*60*24*2) {
    4553           0 :                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
    4554           0 :                         printf("This system appears to set a initial 0 write time\n");
    4555           0 :                         correct = False;
    4556             :                 }
    4557           5 :                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4558             :                         /* SMB2 should always return an inode. */
    4559           0 :                         if (ino == 0) {
    4560           0 :                                 printf("SMB2 bad inode (0)\n");
    4561           0 :                                 correct = false;
    4562             :                         }
    4563             :                 } else {
    4564             :                         /* SMB1 must always return zero here. */
    4565           5 :                         if (ino != 0) {
    4566           0 :                                 printf("SMB1 bad inode (!0)\n");
    4567           0 :                                 correct = false;
    4568             :                         }
    4569             :                 }
    4570             :         }
    4571             : 
    4572           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4573             : 
    4574             : 
    4575             :         /* check if the server updates the directory modification time
    4576             :            when creating a new file */
    4577           5 :         status = cli_mkdir(cli, dname);
    4578           5 :         if (!NT_STATUS_IS_OK(status)) {
    4579           0 :                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
    4580           0 :                 correct = False;
    4581             :         }
    4582           5 :         sleep(3);
    4583           5 :         status = cli_qpathinfo2(cli,
    4584             :                                 "\\trans2\\",
    4585             :                                 &c_time_ts,
    4586             :                                 &a_time_ts,
    4587             :                                 &w_time_ts,
    4588             :                                 &m_time_ts,
    4589             :                                 &size,
    4590             :                                 NULL,
    4591             :                                 NULL,
    4592             :                                 NULL);
    4593           5 :         if (!NT_STATUS_IS_OK(status)) {
    4594           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4595           0 :                 correct = False;
    4596             :         }
    4597             : 
    4598           5 :         cli_openx(cli, fname2, 
    4599             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4600           5 :         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
    4601           5 :         cli_close(cli, fnum);
    4602           5 :         status = cli_qpathinfo2(cli,
    4603             :                                 "\\trans2\\",
    4604             :                                 &c_time_ts,
    4605             :                                 &a_time_ts,
    4606             :                                 &w_time_ts,
    4607             :                                 &m_time2_ts,
    4608             :                                 &size,
    4609             :                                 NULL,
    4610             :                                 NULL,
    4611             :                                 NULL);
    4612           5 :         if (!NT_STATUS_IS_OK(status)) {
    4613           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4614           0 :                 correct = False;
    4615             :         } else {
    4616           5 :                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
    4617             :                     == 0) {
    4618           0 :                         printf("This system does not update directory modification times\n");
    4619           0 :                         correct = False;
    4620             :                 }
    4621             :         }
    4622           5 :         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4623           5 :         cli_rmdir(cli, dname);
    4624             : 
    4625           5 :         if (!torture_close_connection(cli)) {
    4626           0 :                 correct = False;
    4627             :         }
    4628             : 
    4629           5 :         printf("trans2 test finished\n");
    4630             : 
    4631           5 :         return correct;
    4632             : }
    4633             : 
    4634             : /*
    4635             :   This checks new W2K calls.
    4636             : */
    4637             : 
    4638         180 : static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
    4639             : {
    4640         180 :         uint8_t *buf = NULL;
    4641           0 :         uint32_t len;
    4642           0 :         NTSTATUS status;
    4643             : 
    4644         180 :         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
    4645             :                                CLI_BUFFER_SIZE, NULL, &buf, &len);
    4646         180 :         if (!NT_STATUS_IS_OK(status)) {
    4647         180 :                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
    4648             :                        nt_errstr(status));
    4649             :         } else {
    4650           0 :                 printf("qfileinfo: level %d, len = %u\n", level, len);
    4651           0 :                 dump_data(0, (uint8_t *)buf, len);
    4652           0 :                 printf("\n");
    4653             :         }
    4654         180 :         TALLOC_FREE(buf);
    4655         180 :         return status;
    4656             : }
    4657             : 
    4658           5 : static bool run_w2ktest(int dummy)
    4659             : {
    4660           0 :         struct cli_state *cli;
    4661           0 :         uint16_t fnum;
    4662           5 :         const char *fname = "\\w2ktest\\w2k.tst";
    4663           0 :         int level;
    4664           5 :         bool correct = True;
    4665             : 
    4666           5 :         printf("starting w2k test\n");
    4667             : 
    4668           5 :         if (!torture_open_connection(&cli, 0)) {
    4669           0 :                 return False;
    4670             :         }
    4671             : 
    4672           5 :         cli_openx(cli, fname, 
    4673             :                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
    4674             : 
    4675         185 :         for (level = 1004; level < 1040; level++) {
    4676         180 :                 new_trans(cli, fnum, level);
    4677             :         }
    4678             : 
    4679           5 :         cli_close(cli, fnum);
    4680             : 
    4681           5 :         if (!torture_close_connection(cli)) {
    4682           0 :                 correct = False;
    4683             :         }
    4684             : 
    4685           5 :         printf("w2k test finished\n");
    4686             : 
    4687           5 :         return correct;
    4688             : }
    4689             : 
    4690             : 
    4691             : /*
    4692             :   this is a harness for some oplock tests
    4693             :  */
    4694           5 : static bool run_oplock1(int dummy)
    4695             : {
    4696           0 :         struct cli_state *cli1;
    4697           5 :         const char *fname = "\\lockt1.lck";
    4698           0 :         uint16_t fnum1;
    4699           5 :         bool correct = True;
    4700           0 :         NTSTATUS status;
    4701             : 
    4702           5 :         printf("starting oplock test 1\n");
    4703             : 
    4704           5 :         if (!torture_open_connection(&cli1, 0)) {
    4705           0 :                 return False;
    4706             :         }
    4707             : 
    4708           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4709             : 
    4710           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4711             : 
    4712           5 :         cli1->use_oplocks = True;
    4713             : 
    4714           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4715             :                           &fnum1);
    4716           5 :         if (!NT_STATUS_IS_OK(status)) {
    4717           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4718           0 :                 return False;
    4719             :         }
    4720             : 
    4721           5 :         cli1->use_oplocks = False;
    4722             : 
    4723           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4724           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4725             : 
    4726           5 :         status = cli_close(cli1, fnum1);
    4727           5 :         if (!NT_STATUS_IS_OK(status)) {
    4728           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4729           0 :                 return False;
    4730             :         }
    4731             : 
    4732           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4733           5 :         if (!NT_STATUS_IS_OK(status)) {
    4734           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4735           0 :                 return False;
    4736             :         }
    4737             : 
    4738           5 :         if (!torture_close_connection(cli1)) {
    4739           0 :                 correct = False;
    4740             :         }
    4741             : 
    4742           5 :         printf("finished oplock test 1\n");
    4743             : 
    4744           5 :         return correct;
    4745             : }
    4746             : 
    4747           4 : static bool run_oplock2(int dummy)
    4748             : {
    4749           0 :         struct cli_state *cli1, *cli2;
    4750           4 :         const char *fname = "\\lockt2.lck";
    4751           0 :         uint16_t fnum1, fnum2;
    4752           4 :         int saved_use_oplocks = use_oplocks;
    4753           0 :         char buf[4];
    4754           4 :         bool correct = True;
    4755           0 :         volatile bool *shared_correct;
    4756           0 :         size_t nread;
    4757           0 :         NTSTATUS status;
    4758             : 
    4759           4 :         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
    4760           4 :         *shared_correct = True;
    4761             : 
    4762           4 :         use_level_II_oplocks = True;
    4763           4 :         use_oplocks = True;
    4764             : 
    4765           4 :         printf("starting oplock test 2\n");
    4766             : 
    4767           4 :         if (!torture_open_connection(&cli1, 0)) {
    4768           0 :                 use_level_II_oplocks = False;
    4769           0 :                 use_oplocks = saved_use_oplocks;
    4770           0 :                 return False;
    4771             :         }
    4772             : 
    4773           4 :         if (!torture_open_connection(&cli2, 1)) {
    4774           0 :                 use_level_II_oplocks = False;
    4775           0 :                 use_oplocks = saved_use_oplocks;
    4776           0 :                 return False;
    4777             :         }
    4778             : 
    4779           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4780             : 
    4781           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4782           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4783             : 
    4784           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4785             :                           &fnum1);
    4786           4 :         if (!NT_STATUS_IS_OK(status)) {
    4787           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4788           0 :                 return False;
    4789             :         }
    4790             : 
    4791             :         /* Don't need the globals any more. */
    4792           4 :         use_level_II_oplocks = False;
    4793           4 :         use_oplocks = saved_use_oplocks;
    4794             : 
    4795           4 :         if (fork() == 0) {
    4796             :                 /* Child code */
    4797           4 :                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    4798           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4799           0 :                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
    4800           0 :                         *shared_correct = False;
    4801           0 :                         exit(0);
    4802             :                 }
    4803             : 
    4804           4 :                 sleep(2);
    4805             : 
    4806           4 :                 status = cli_close(cli2, fnum2);
    4807           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4808           0 :                         printf("close2 failed (%s)\n", nt_errstr(status));
    4809           0 :                         *shared_correct = False;
    4810             :                 }
    4811             : 
    4812           4 :                 exit(0);
    4813             :         }
    4814             : 
    4815           4 :         sleep(2);
    4816             : 
    4817             :         /* Ensure cli1 processes the break. Empty file should always return 0
    4818             :          * bytes.  */
    4819           4 :         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
    4820           4 :         if (!NT_STATUS_IS_OK(status)) {
    4821           0 :                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
    4822           0 :                 correct = false;
    4823           4 :         } else if (nread != 0) {
    4824           0 :                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
    4825             :                       (unsigned long)nread, 0);
    4826           0 :                 correct = false;
    4827             :         }
    4828             : 
    4829             :         /* Should now be at level II. */
    4830             :         /* Test if sending a write locks causes a break to none. */
    4831           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
    4832           4 :         if (!NT_STATUS_IS_OK(status)) {
    4833           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4834           0 :                 correct = False;
    4835             :         }
    4836             : 
    4837           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4838             : 
    4839           4 :         sleep(2);
    4840             : 
    4841           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    4842           4 :         if (!NT_STATUS_IS_OK(status)) {
    4843           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4844           0 :                 correct = False;
    4845             :         }
    4846             : 
    4847           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4848             : 
    4849           4 :         sleep(2);
    4850             : 
    4851           4 :         cli_read(cli1, fnum1, buf, 0, 4, NULL);
    4852             : 
    4853           4 :         status = cli_close(cli1, fnum1);
    4854           4 :         if (!NT_STATUS_IS_OK(status)) {
    4855           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4856           0 :                 correct = False;
    4857             :         }
    4858             : 
    4859           4 :         sleep(4);
    4860             : 
    4861           4 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4862           4 :         if (!NT_STATUS_IS_OK(status)) {
    4863           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4864           0 :                 correct = False;
    4865             :         }
    4866             : 
    4867           4 :         if (!torture_close_connection(cli1)) {
    4868           0 :                 correct = False;
    4869             :         }
    4870             : 
    4871           4 :         if (!*shared_correct) {
    4872           0 :                 correct = False;
    4873             :         }
    4874             : 
    4875           4 :         printf("finished oplock test 2\n");
    4876             : 
    4877           4 :         return correct;
    4878             : }
    4879             : 
    4880             : struct oplock4_state {
    4881             :         struct tevent_context *ev;
    4882             :         struct cli_state *cli;
    4883             :         bool *got_break;
    4884             :         uint16_t *fnum2;
    4885             : };
    4886             : 
    4887             : static void oplock4_got_break(struct tevent_req *req);
    4888             : static void oplock4_got_open(struct tevent_req *req);
    4889             : 
    4890           5 : static bool run_oplock4(int dummy)
    4891             : {
    4892           0 :         struct tevent_context *ev;
    4893           0 :         struct cli_state *cli1, *cli2;
    4894           0 :         struct tevent_req *oplock_req, *open_req;
    4895           5 :         const char *fname = "\\lockt4.lck";
    4896           5 :         const char *fname_ln = "\\lockt4_ln.lck";
    4897           0 :         uint16_t fnum1, fnum2;
    4898           5 :         int saved_use_oplocks = use_oplocks;
    4899           0 :         NTSTATUS status;
    4900           5 :         bool correct = true;
    4901             : 
    4902           0 :         bool got_break;
    4903             : 
    4904           0 :         struct oplock4_state *state;
    4905             : 
    4906           5 :         printf("starting oplock test 4\n");
    4907             : 
    4908           5 :         if (!torture_open_connection(&cli1, 0)) {
    4909           0 :                 use_level_II_oplocks = false;
    4910           0 :                 use_oplocks = saved_use_oplocks;
    4911           0 :                 return false;
    4912             :         }
    4913             : 
    4914           5 :         if (!torture_open_connection(&cli2, 1)) {
    4915           0 :                 use_level_II_oplocks = false;
    4916           0 :                 use_oplocks = saved_use_oplocks;
    4917           0 :                 return false;
    4918             :         }
    4919             : 
    4920           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4921           5 :         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4922             : 
    4923           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4924           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4925             : 
    4926             :         /* Create the file. */
    4927           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4928             :                           &fnum1);
    4929           5 :         if (!NT_STATUS_IS_OK(status)) {
    4930           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4931           0 :                 return false;
    4932             :         }
    4933             : 
    4934           5 :         status = cli_close(cli1, fnum1);
    4935           5 :         if (!NT_STATUS_IS_OK(status)) {
    4936           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4937           0 :                 return false;
    4938             :         }
    4939             : 
    4940             :         /* Now create a hardlink. */
    4941           5 :         status = cli_hardlink(cli1, fname, fname_ln);
    4942           5 :         if (!NT_STATUS_IS_OK(status)) {
    4943           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    4944           0 :                 return false;
    4945             :         }
    4946             : 
    4947             :         /* Prove that opening hardlinks cause deny modes to conflict. */
    4948           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
    4949           5 :         if (!NT_STATUS_IS_OK(status)) {
    4950           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4951           0 :                 return false;
    4952             :         }
    4953             : 
    4954           5 :         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
    4955           5 :         if (NT_STATUS_IS_OK(status)) {
    4956           0 :                 printf("open of %s succeeded - should fail with sharing violation.\n",
    4957             :                         fname_ln);
    4958           0 :                 return false;
    4959             :         }
    4960             : 
    4961           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    4962           0 :                 printf("open of %s should fail with sharing violation. Got %s\n",
    4963             :                         fname_ln, nt_errstr(status));
    4964           0 :                 return false;
    4965             :         }
    4966             : 
    4967           5 :         status = cli_close(cli1, fnum1);
    4968           5 :         if (!NT_STATUS_IS_OK(status)) {
    4969           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4970           0 :                 return false;
    4971             :         }
    4972             : 
    4973           5 :         cli1->use_oplocks = true;
    4974           5 :         cli2->use_oplocks = true;
    4975             : 
    4976           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    4977           5 :         if (!NT_STATUS_IS_OK(status)) {
    4978           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4979           0 :                 return false;
    4980             :         }
    4981             : 
    4982           5 :         ev = samba_tevent_context_init(talloc_tos());
    4983           5 :         if (ev == NULL) {
    4984           0 :                 printf("tevent_context_init failed\n");
    4985           0 :                 return false;
    4986             :         }
    4987             : 
    4988           5 :         state = talloc(ev, struct oplock4_state);
    4989           5 :         if (state == NULL) {
    4990           0 :                 printf("talloc failed\n");
    4991           0 :                 return false;
    4992             :         }
    4993           5 :         state->ev = ev;
    4994           5 :         state->cli = cli1;
    4995           5 :         state->got_break = &got_break;
    4996           5 :         state->fnum2 = &fnum2;
    4997             : 
    4998           5 :         oplock_req = cli_smb_oplock_break_waiter_send(
    4999             :                 talloc_tos(), ev, cli1);
    5000           5 :         if (oplock_req == NULL) {
    5001           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    5002           0 :                 return false;
    5003             :         }
    5004           5 :         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
    5005             : 
    5006           5 :         open_req = cli_openx_send(
    5007             :                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
    5008           5 :         if (open_req == NULL) {
    5009           0 :                 printf("cli_openx_send failed\n");
    5010           0 :                 return false;
    5011             :         }
    5012           5 :         tevent_req_set_callback(open_req, oplock4_got_open, state);
    5013             : 
    5014           5 :         got_break = false;
    5015           5 :         fnum2 = 0xffff;
    5016             : 
    5017          40 :         while (!got_break || fnum2 == 0xffff) {
    5018           0 :                 int ret;
    5019          35 :                 ret = tevent_loop_once(ev);
    5020          35 :                 if (ret == -1) {
    5021           0 :                         printf("tevent_loop_once failed: %s\n",
    5022           0 :                                strerror(errno));
    5023           0 :                         return false;
    5024             :                 }
    5025             :         }
    5026             : 
    5027           5 :         status = cli_close(cli2, fnum2);
    5028           5 :         if (!NT_STATUS_IS_OK(status)) {
    5029           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    5030           0 :                 correct = false;
    5031             :         }
    5032             : 
    5033           5 :         status = cli_close(cli1, fnum1);
    5034           5 :         if (!NT_STATUS_IS_OK(status)) {
    5035           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    5036           0 :                 correct = false;
    5037             :         }
    5038             : 
    5039           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5040           5 :         if (!NT_STATUS_IS_OK(status)) {
    5041           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5042           0 :                 correct = false;
    5043             :         }
    5044             : 
    5045           5 :         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5046           5 :         if (!NT_STATUS_IS_OK(status)) {
    5047           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5048           0 :                 correct = false;
    5049             :         }
    5050             : 
    5051           5 :         if (!torture_close_connection(cli1)) {
    5052           0 :                 correct = false;
    5053             :         }
    5054             : 
    5055           5 :         if (!got_break) {
    5056           0 :                 correct = false;
    5057             :         }
    5058             : 
    5059           5 :         printf("finished oplock test 4\n");
    5060             : 
    5061           5 :         return correct;
    5062             : }
    5063             : 
    5064           5 : static void oplock4_got_break(struct tevent_req *req)
    5065             : {
    5066           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5067             :                 req, struct oplock4_state);
    5068           0 :         uint16_t fnum;
    5069           0 :         uint8_t level;
    5070           0 :         NTSTATUS status;
    5071             : 
    5072           5 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    5073           5 :         TALLOC_FREE(req);
    5074           5 :         if (!NT_STATUS_IS_OK(status)) {
    5075           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    5076             :                        nt_errstr(status));
    5077           0 :                 return;
    5078             :         }
    5079           5 :         *state->got_break = true;
    5080             : 
    5081           5 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    5082             :                                   NO_OPLOCK);
    5083           5 :         if (req == NULL) {
    5084           0 :                 printf("cli_oplock_ack_send failed\n");
    5085           0 :                 return;
    5086             :         }
    5087             : }
    5088             : 
    5089           5 : static void oplock4_got_open(struct tevent_req *req)
    5090             : {
    5091           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5092             :                 req, struct oplock4_state);
    5093           0 :         NTSTATUS status;
    5094             : 
    5095           5 :         status = cli_openx_recv(req, state->fnum2);
    5096           5 :         if (!NT_STATUS_IS_OK(status)) {
    5097           0 :                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
    5098           0 :                 *state->fnum2 = 0xffff;
    5099             :         }
    5100           5 : }
    5101             : 
    5102             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
    5103             : 
    5104             : struct oplock5_state {
    5105             :         int pipe_down_fd;
    5106             : };
    5107             : 
    5108             : /*
    5109             :  * Async open the file that has a kernel oplock, do an echo to get
    5110             :  * that 100% across, close the file to signal to the child fd that the
    5111             :  * oplock can be dropped, wait for the open reply.
    5112             :  */
    5113             : 
    5114             : static void oplock5_opened(struct tevent_req *subreq);
    5115             : static void oplock5_pong(struct tevent_req *subreq);
    5116             : static void oplock5_timedout(struct tevent_req *subreq);
    5117             : 
    5118           1 : static struct tevent_req *oplock5_send(
    5119             :         TALLOC_CTX *mem_ctx,
    5120             :         struct tevent_context *ev,
    5121             :         struct cli_state *cli,
    5122             :         const char *fname,
    5123             :         int pipe_down_fd)
    5124             : {
    5125           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    5126           1 :         struct oplock5_state *state = NULL;
    5127           0 :         static uint8_t data = 0;
    5128             : 
    5129           1 :         req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
    5130           1 :         if (req == NULL) {
    5131           0 :                 return NULL;
    5132             :         }
    5133           1 :         state->pipe_down_fd = pipe_down_fd;
    5134             : 
    5135           1 :         subreq = cli_ntcreate_send(
    5136             :                 state,
    5137             :                 ev,
    5138             :                 cli,
    5139             :                 fname,
    5140             :                 0,                      /* CreatFlags */
    5141             :                 SEC_FILE_READ_DATA,    /* DesiredAccess */
    5142             :                 FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
    5143             :                 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
    5144             :                 FILE_OPEN,               /* CreateDisposition */
    5145             :                 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
    5146             :                 0,                       /* Impersonation */
    5147             :                 0);                      /* SecurityFlags */
    5148           1 :         if (tevent_req_nomem(subreq, req)) {
    5149           0 :                 return tevent_req_post(req, ev);
    5150             :         }
    5151           1 :         tevent_req_set_callback(subreq, oplock5_opened, req);
    5152             : 
    5153           1 :         subreq = cli_echo_send(
    5154             :                 state,
    5155             :                 ev,
    5156             :                 cli,
    5157             :                 1,
    5158           1 :                 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
    5159           1 :         if (tevent_req_nomem(subreq, req)) {
    5160           0 :                 return tevent_req_post(req, ev);
    5161             :         }
    5162           1 :         tevent_req_set_callback(subreq, oplock5_pong, req);
    5163             : 
    5164           1 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
    5165           1 :         if (tevent_req_nomem(subreq, req)) {
    5166           0 :                 return tevent_req_post(req, ev);
    5167             :         }
    5168           1 :         tevent_req_set_callback(subreq, oplock5_timedout, req);
    5169             : 
    5170           1 :         return req;
    5171             : }
    5172             : 
    5173           1 : static void oplock5_opened(struct tevent_req *subreq)
    5174             : {
    5175           1 :         struct tevent_req *req = tevent_req_callback_data(
    5176             :                 subreq, struct tevent_req);
    5177           0 :         NTSTATUS status;
    5178           0 :         uint16_t fnum;
    5179             : 
    5180           1 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
    5181           1 :         TALLOC_FREE(subreq);
    5182           1 :         if (tevent_req_nterror(req, status)) {
    5183           0 :                 return;
    5184             :         }
    5185           1 :         tevent_req_done(req);
    5186             : }
    5187             : 
    5188           1 : static void oplock5_pong(struct tevent_req *subreq)
    5189             : {
    5190           1 :         struct tevent_req *req = tevent_req_callback_data(
    5191             :                 subreq, struct tevent_req);
    5192           1 :         struct oplock5_state *state = tevent_req_data(
    5193             :                 req, struct oplock5_state);
    5194           0 :         NTSTATUS status;
    5195             : 
    5196           1 :         status = cli_echo_recv(subreq);
    5197           1 :         TALLOC_FREE(subreq);
    5198           1 :         if (tevent_req_nterror(req, status)) {
    5199           0 :                 return;
    5200             :         }
    5201             : 
    5202           1 :         close(state->pipe_down_fd);
    5203             : }
    5204             : 
    5205           0 : static void oplock5_timedout(struct tevent_req *subreq)
    5206             : {
    5207           0 :         struct tevent_req *req = tevent_req_callback_data(
    5208             :                 subreq, struct tevent_req);
    5209           0 :         bool ok;
    5210             : 
    5211           0 :         ok = tevent_wakeup_recv(subreq);
    5212           0 :         TALLOC_FREE(subreq);
    5213           0 :         if (!ok) {
    5214           0 :                 tevent_req_oom(req);
    5215           0 :                 return;
    5216             :         }
    5217           0 :         tevent_req_nterror(req, NT_STATUS_TIMEOUT);
    5218             : }
    5219             : 
    5220           1 : static NTSTATUS oplock5_recv(struct tevent_req *req)
    5221             : {
    5222           1 :         return tevent_req_simple_recv_ntstatus(req);
    5223             : }
    5224             : 
    5225           1 : static bool run_oplock5(int dummy)
    5226             : {
    5227           1 :         struct tevent_context *ev = NULL;
    5228           1 :         struct tevent_req *req = NULL;
    5229           1 :         struct cli_state *cli = NULL;
    5230           1 :         const char *fname = "oplock5.txt";
    5231           0 :         int pipe_down[2], pipe_up[2];
    5232           0 :         pid_t child_pid;
    5233           1 :         uint8_t c = '\0';
    5234           0 :         NTSTATUS status;
    5235           0 :         int ret;
    5236           0 :         bool ok;
    5237             : 
    5238           1 :         printf("starting oplock5\n");
    5239             : 
    5240           1 :         if (local_path == NULL) {
    5241           0 :                 d_fprintf(stderr, "oplock5 must be given a local path via "
    5242             :                           "-l <localpath>\n");
    5243           0 :                 return false;
    5244             :         }
    5245             : 
    5246           1 :         ret = pipe(pipe_down);
    5247           1 :         if (ret == -1) {
    5248           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5249           0 :                 return false;
    5250             :         }
    5251           1 :         ret = pipe(pipe_up);
    5252           1 :         if (ret == -1) {
    5253           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5254           0 :                 return false;
    5255             :         }
    5256             : 
    5257           1 :         child_pid = fork();
    5258           2 :         if (child_pid == -1) {
    5259           0 :                 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
    5260           0 :                 return false;
    5261             :         }
    5262             : 
    5263           2 :         if (child_pid == 0) {
    5264           1 :                 char *local_file = NULL;
    5265           0 :                 int fd;
    5266             : 
    5267           1 :                 close(pipe_down[1]);
    5268           1 :                 close(pipe_up[0]);
    5269             : 
    5270           1 :                 local_file = talloc_asprintf(
    5271           1 :                         talloc_tos(), "%s/%s", local_path, fname);
    5272           1 :                 if (local_file == 0) {
    5273           0 :                         c = 1;
    5274           0 :                         goto do_write;
    5275             :                 }
    5276           1 :                 fd = open(local_file, O_RDWR|O_CREAT, 0644);
    5277           1 :                 if (fd == -1) {
    5278           0 :                         d_fprintf(stderr,
    5279             :                                   "open(%s) in child failed: %s\n",
    5280             :                                   local_file,
    5281           0 :                                   strerror(errno));
    5282           0 :                         c = 2;
    5283           0 :                         goto do_write;
    5284             :                 }
    5285             : 
    5286           1 :                 signal(SIGIO, SIG_IGN);
    5287             : 
    5288           1 :                 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
    5289           1 :                 if (ret == -1) {
    5290           0 :                         d_fprintf(stderr,
    5291             :                                   "SETLEASE in child failed: %s\n",
    5292           0 :                                   strerror(errno));
    5293           0 :                         c = 3;
    5294           0 :                         goto do_write;
    5295             :                 }
    5296             : 
    5297           1 :         do_write:
    5298           1 :                 ret = sys_write(pipe_up[1], &c, sizeof(c));
    5299           1 :                 if (ret == -1) {
    5300           0 :                         d_fprintf(stderr,
    5301             :                                   "sys_write failed: %s\n",
    5302           0 :                                   strerror(errno));
    5303           0 :                         exit(4);
    5304             :                 }
    5305           1 :                 ret = sys_read(pipe_down[0], &c, sizeof(c));
    5306           1 :                 if (ret == -1) {
    5307           0 :                         d_fprintf(stderr,
    5308             :                                   "sys_read failed: %s\n",
    5309           0 :                                   strerror(errno));
    5310           0 :                         exit(5);
    5311             :                 }
    5312           1 :                 exit(0);
    5313             :         }
    5314             : 
    5315           1 :         close(pipe_up[1]);
    5316           1 :         close(pipe_down[0]);
    5317             : 
    5318           1 :         ret = sys_read(pipe_up[0], &c, sizeof(c));
    5319           1 :         if (ret != 1) {
    5320           0 :                 d_fprintf(stderr,
    5321             :                           "sys_read failed: %s\n",
    5322           0 :                           strerror(errno));
    5323           0 :                 return false;
    5324             :         }
    5325           1 :         if (c != 0) {
    5326           0 :                 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
    5327           0 :                 return false;
    5328             :         }
    5329             : 
    5330           1 :         ok = torture_open_connection(&cli, 0);
    5331           1 :         if (!ok) {
    5332           0 :                 d_fprintf(stderr, "torture_open_connection failed\n");
    5333           0 :                 return false;
    5334             :         }
    5335             : 
    5336           1 :         ev = samba_tevent_context_init(talloc_tos());
    5337           1 :         if (ev == NULL) {
    5338           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5339           0 :                 return false;
    5340             :         }
    5341             : 
    5342           1 :         req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
    5343           1 :         if (req == NULL) {
    5344           0 :                 d_fprintf(stderr, "oplock5_send failed\n");
    5345           0 :                 return false;
    5346             :         }
    5347             : 
    5348           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5349           1 :         if (!ok) {
    5350           0 :                 d_fprintf(stderr,
    5351             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5352             :                           nt_errstr(status));
    5353           0 :                 return false;
    5354             :         }
    5355             : 
    5356           1 :         status = oplock5_recv(req);
    5357           1 :         TALLOC_FREE(req);
    5358           1 :         if (!NT_STATUS_IS_OK(status)) {
    5359           0 :                 d_fprintf(stderr,
    5360             :                           "oplock5 failed: %s\n",
    5361             :                           nt_errstr(status));
    5362           0 :                 return false;
    5363             :         }
    5364             : 
    5365           1 :         return true;
    5366             : }
    5367             : 
    5368             : #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
    5369             : 
    5370             : /*
    5371             :   Test delete on close semantics.
    5372             :  */
    5373           5 : static bool run_deletetest(int dummy)
    5374             : {
    5375           5 :         struct cli_state *cli1 = NULL;
    5376           5 :         struct cli_state *cli2 = NULL;
    5377           5 :         const char *fname = "\\delete.file";
    5378           5 :         uint16_t fnum1 = (uint16_t)-1;
    5379           5 :         uint16_t fnum2 = (uint16_t)-1;
    5380           5 :         bool correct = false;
    5381           0 :         NTSTATUS status;
    5382             : 
    5383           5 :         printf("starting delete test\n");
    5384             : 
    5385           5 :         if (!torture_open_connection(&cli1, 0)) {
    5386           0 :                 return False;
    5387             :         }
    5388             : 
    5389           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5390             : 
    5391             :         /* Test 1 - this should delete the file on close. */
    5392             : 
    5393           5 :         cli_setatr(cli1, fname, 0, 0);
    5394           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5395             : 
    5396           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5397             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5398             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5399           5 :         if (!NT_STATUS_IS_OK(status)) {
    5400           0 :                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
    5401           0 :                 goto fail;
    5402             :         }
    5403             : 
    5404           5 :         status = cli_close(cli1, fnum1);
    5405           5 :         if (!NT_STATUS_IS_OK(status)) {
    5406           0 :                 printf("[1] close failed (%s)\n", nt_errstr(status));
    5407           0 :                 goto fail;
    5408             :         }
    5409             : 
    5410           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    5411           5 :         if (NT_STATUS_IS_OK(status)) {
    5412           0 :                 printf("[1] open of %s succeeded (should fail)\n", fname);
    5413           0 :                 goto fail;
    5414             :         }
    5415             : 
    5416           5 :         printf("first delete on close test succeeded.\n");
    5417             : 
    5418             :         /* Test 2 - this should delete the file on close. */
    5419             : 
    5420           5 :         cli_setatr(cli1, fname, 0, 0);
    5421           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5422             : 
    5423           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5424             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5425             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5426           5 :         if (!NT_STATUS_IS_OK(status)) {
    5427           0 :                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
    5428           0 :                 goto fail;
    5429             :         }
    5430             : 
    5431           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5432           5 :         if (!NT_STATUS_IS_OK(status)) {
    5433           0 :                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5434           0 :                 goto fail;
    5435             :         }
    5436             : 
    5437           5 :         status = cli_close(cli1, fnum1);
    5438           5 :         if (!NT_STATUS_IS_OK(status)) {
    5439           0 :                 printf("[2] close failed (%s)\n", nt_errstr(status));
    5440           0 :                 goto fail;
    5441             :         }
    5442             : 
    5443           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5444           5 :         if (NT_STATUS_IS_OK(status)) {
    5445           0 :                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
    5446           0 :                 status = cli_close(cli1, fnum1);
    5447           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5448           0 :                         printf("[2] close failed (%s)\n", nt_errstr(status));
    5449             :                 }
    5450           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5451           0 :                 goto fail;
    5452             :         }
    5453             : 
    5454           5 :         printf("second delete on close test succeeded.\n");
    5455             : 
    5456             :         /* Test 3 - ... */
    5457           5 :         cli_setatr(cli1, fname, 0, 0);
    5458           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5459             : 
    5460           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5461             :                               FILE_ATTRIBUTE_NORMAL,
    5462             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5463             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5464           5 :         if (!NT_STATUS_IS_OK(status)) {
    5465           0 :                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5466           0 :                 goto fail;
    5467             :         }
    5468             : 
    5469             :         /* This should fail with a sharing violation - open for delete is only compatible
    5470             :            with SHARE_DELETE. */
    5471             : 
    5472           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5473             :                               FILE_ATTRIBUTE_NORMAL,
    5474             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5475             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5476           5 :         if (NT_STATUS_IS_OK(status)) {
    5477           0 :                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
    5478           0 :                 goto fail;
    5479             :         }
    5480             : 
    5481             :         /* This should succeed. */
    5482           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5483             :                              FILE_ATTRIBUTE_NORMAL,
    5484             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5485             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5486           5 :         if (!NT_STATUS_IS_OK(status)) {
    5487           0 :                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
    5488           0 :                 goto fail;
    5489             :         }
    5490             : 
    5491           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5492           5 :         if (!NT_STATUS_IS_OK(status)) {
    5493           0 :                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5494           0 :                 goto fail;
    5495             :         }
    5496             : 
    5497           5 :         status = cli_close(cli1, fnum1);
    5498           5 :         if (!NT_STATUS_IS_OK(status)) {
    5499           0 :                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
    5500           0 :                 goto fail;
    5501             :         }
    5502             : 
    5503           5 :         status = cli_close(cli1, fnum2);
    5504           5 :         if (!NT_STATUS_IS_OK(status)) {
    5505           0 :                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
    5506           0 :                 goto fail;
    5507             :         }
    5508             : 
    5509             :         /* This should fail - file should no longer be there. */
    5510             : 
    5511           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5512           5 :         if (NT_STATUS_IS_OK(status)) {
    5513           0 :                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
    5514           0 :                 status = cli_close(cli1, fnum1);
    5515           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5516           0 :                         printf("[3] close failed (%s)\n", nt_errstr(status));
    5517             :                 }
    5518           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5519           0 :                 goto fail;
    5520             :         }
    5521             : 
    5522           5 :         printf("third delete on close test succeeded.\n");
    5523             : 
    5524             :         /* Test 4 ... */
    5525           5 :         cli_setatr(cli1, fname, 0, 0);
    5526           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5527             : 
    5528           5 :         status = cli_ntcreate(cli1, fname, 0,
    5529             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5530             :                               FILE_ATTRIBUTE_NORMAL,
    5531             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5532             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5533           5 :         if (!NT_STATUS_IS_OK(status)) {
    5534           0 :                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
    5535           0 :                 goto fail;
    5536             :         }
    5537             : 
    5538             :         /* This should succeed. */
    5539           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5540             :                              FILE_ATTRIBUTE_NORMAL,
    5541             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5542             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5543           5 :         if (!NT_STATUS_IS_OK(status)) {
    5544           0 :                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5545           0 :                 goto fail;
    5546             :         }
    5547             : 
    5548           5 :         status = cli_close(cli1, fnum2);
    5549           5 :         if (!NT_STATUS_IS_OK(status)) {
    5550           0 :                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
    5551           0 :                 goto fail;
    5552             :         }
    5553             : 
    5554           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5555           5 :         if (!NT_STATUS_IS_OK(status)) {
    5556           0 :                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5557           0 :                 goto fail;
    5558             :         }
    5559             : 
    5560             :         /* This should fail - no more opens once delete on close set. */
    5561           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5562             :                               FILE_ATTRIBUTE_NORMAL,
    5563             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5564             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5565           5 :         if (NT_STATUS_IS_OK(status)) {
    5566           0 :                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
    5567           0 :                 goto fail;
    5568             :         }
    5569             : 
    5570           5 :         status = cli_close(cli1, fnum1);
    5571           5 :         if (!NT_STATUS_IS_OK(status)) {
    5572           0 :                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
    5573           0 :                 goto fail;
    5574             :         }
    5575             : 
    5576           5 :         printf("fourth delete on close test succeeded.\n");
    5577             : 
    5578             :         /* Test 5 ... */
    5579           5 :         cli_setatr(cli1, fname, 0, 0);
    5580           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5581             : 
    5582           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
    5583           5 :         if (!NT_STATUS_IS_OK(status)) {
    5584           0 :                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
    5585           0 :                 goto fail;
    5586             :         }
    5587             : 
    5588             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5589             : 
    5590           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5591           5 :         if (NT_STATUS_IS_OK(status)) {
    5592           0 :                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
    5593           0 :                 goto fail;
    5594             :         }
    5595             : 
    5596           5 :         status = cli_close(cli1, fnum1);
    5597           5 :         if (!NT_STATUS_IS_OK(status)) {
    5598           0 :                 printf("[5] close failed (%s)\n", nt_errstr(status));
    5599           0 :                 goto fail;
    5600             :         }
    5601             : 
    5602           5 :         printf("fifth delete on close test succeeded.\n");
    5603             : 
    5604             :         /* Test 6 ... */
    5605           5 :         cli_setatr(cli1, fname, 0, 0);
    5606           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5607             : 
    5608           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5609             :                              FILE_ATTRIBUTE_NORMAL,
    5610             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5611             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5612           5 :         if (!NT_STATUS_IS_OK(status)) {
    5613           0 :                 printf("[6] open of %s failed (%s)\n", fname,
    5614             :                        nt_errstr(status));
    5615           0 :                 goto fail;
    5616             :         }
    5617             : 
    5618             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5619             : 
    5620           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5621           5 :         if (NT_STATUS_IS_OK(status)) {
    5622           0 :                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
    5623           0 :                 goto fail;
    5624             :         }
    5625             : 
    5626           5 :         status = cli_close(cli1, fnum1);
    5627           5 :         if (!NT_STATUS_IS_OK(status)) {
    5628           0 :                 printf("[6] close failed (%s)\n", nt_errstr(status));
    5629           0 :                 goto fail;
    5630             :         }
    5631             : 
    5632           5 :         printf("sixth delete on close test succeeded.\n");
    5633             : 
    5634             :         /* Test 7 ... */
    5635           5 :         cli_setatr(cli1, fname, 0, 0);
    5636           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5637             : 
    5638           5 :         status = cli_ntcreate(cli1, fname, 0,
    5639             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5640             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5641             :                               0, 0, &fnum1, NULL);
    5642           5 :         if (!NT_STATUS_IS_OK(status)) {
    5643           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5644           0 :                 goto fail;
    5645             :         }
    5646             : 
    5647           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5648           5 :         if (!NT_STATUS_IS_OK(status)) {
    5649           0 :                 printf("[7] setting delete_on_close on file failed !\n");
    5650           0 :                 goto fail;
    5651             :         }
    5652             : 
    5653           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5654           5 :         if (!NT_STATUS_IS_OK(status)) {
    5655           0 :                 printf("[7] unsetting delete_on_close on file failed !\n");
    5656           0 :                 goto fail;
    5657             :         }
    5658             : 
    5659           5 :         status = cli_close(cli1, fnum1);
    5660           5 :         if (!NT_STATUS_IS_OK(status)) {
    5661           0 :                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
    5662           0 :                 goto fail;
    5663             :         }
    5664             : 
    5665             :         /* This next open should succeed - we reset the flag. */
    5666           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5667           5 :         if (!NT_STATUS_IS_OK(status)) {
    5668           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5669           0 :                 goto fail;
    5670             :         }
    5671             : 
    5672           5 :         status = cli_close(cli1, fnum1);
    5673           5 :         if (!NT_STATUS_IS_OK(status)) {
    5674           0 :                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
    5675           0 :                 goto fail;
    5676             :         }
    5677             : 
    5678           5 :         printf("seventh delete on close test succeeded.\n");
    5679             : 
    5680             :         /* Test 8 ... */
    5681           5 :         cli_setatr(cli1, fname, 0, 0);
    5682           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5683             : 
    5684           5 :         if (!torture_open_connection(&cli2, 1)) {
    5685           0 :                 printf("[8] failed to open second connection.\n");
    5686           0 :                 goto fail;
    5687             :         }
    5688             : 
    5689           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5690             : 
    5691           5 :         status = cli_ntcreate(cli1, fname, 0,
    5692             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5693             :                              FILE_ATTRIBUTE_NORMAL,
    5694             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5695             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5696           5 :         if (!NT_STATUS_IS_OK(status)) {
    5697           0 :                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5698           0 :                 goto fail;
    5699             :         }
    5700             : 
    5701           5 :         status = cli_ntcreate(cli2, fname, 0,
    5702             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5703             :                              FILE_ATTRIBUTE_NORMAL,
    5704             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5705             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5706           5 :         if (!NT_STATUS_IS_OK(status)) {
    5707           0 :                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5708           0 :                 goto fail;
    5709             :         }
    5710             : 
    5711           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5712           5 :         if (!NT_STATUS_IS_OK(status)) {
    5713           0 :                 printf("[8] setting delete_on_close on file failed !\n");
    5714           0 :                 goto fail;
    5715             :         }
    5716             : 
    5717           5 :         status = cli_close(cli1, fnum1);
    5718           5 :         if (!NT_STATUS_IS_OK(status)) {
    5719           0 :                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
    5720           0 :                 goto fail;
    5721             :         }
    5722             : 
    5723           5 :         status = cli_close(cli2, fnum2);
    5724           5 :         if (!NT_STATUS_IS_OK(status)) {
    5725           0 :                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
    5726           0 :                 goto fail;
    5727             :         }
    5728             : 
    5729             :         /* This should fail.. */
    5730           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5731           5 :         if (NT_STATUS_IS_OK(status)) {
    5732           0 :                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
    5733           0 :                 goto fail;
    5734             :         }
    5735             : 
    5736           5 :         printf("eighth delete on close test succeeded.\n");
    5737             : 
    5738             :         /* Test 9 ... */
    5739             : 
    5740             :         /* This should fail - we need to set DELETE_ACCESS. */
    5741           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5742             :                               FILE_ATTRIBUTE_NORMAL,
    5743             :                               FILE_SHARE_NONE,
    5744             :                               FILE_OVERWRITE_IF,
    5745             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5746           5 :         if (NT_STATUS_IS_OK(status)) {
    5747           0 :                 printf("[9] open of %s succeeded should have failed!\n", fname);
    5748           0 :                 goto fail;
    5749             :         }
    5750             : 
    5751           5 :         printf("ninth delete on close test succeeded.\n");
    5752             : 
    5753             :         /* Test 10 ... */
    5754             : 
    5755           5 :         status = cli_ntcreate(cli1, fname, 0,
    5756             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5757             :                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5758             :                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
    5759             :                              0, &fnum1, NULL);
    5760           5 :         if (!NT_STATUS_IS_OK(status)) {
    5761           0 :                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
    5762           0 :                 goto fail;
    5763             :         }
    5764             : 
    5765             :         /* This should delete the file. */
    5766           5 :         status = cli_close(cli1, fnum1);
    5767           5 :         if (!NT_STATUS_IS_OK(status)) {
    5768           0 :                 printf("[10] close failed (%s)\n", nt_errstr(status));
    5769           0 :                 goto fail;
    5770             :         }
    5771             : 
    5772             :         /* This should fail.. */
    5773           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5774           5 :         if (NT_STATUS_IS_OK(status)) {
    5775           0 :                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
    5776           0 :                 goto fail;
    5777             :         }
    5778             : 
    5779           5 :         printf("tenth delete on close test succeeded.\n");
    5780             : 
    5781             :         /* Test 11 ... */
    5782             : 
    5783           5 :         cli_setatr(cli1, fname, 0, 0);
    5784           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5785             : 
    5786             :         /* Can we open a read-only file with delete access? */
    5787             : 
    5788             :         /* Create a readonly file. */
    5789           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5790             :                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
    5791             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5792           5 :         if (!NT_STATUS_IS_OK(status)) {
    5793           0 :                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
    5794           0 :                 goto fail;
    5795             :         }
    5796             : 
    5797           5 :         status = cli_close(cli1, fnum1);
    5798           5 :         if (!NT_STATUS_IS_OK(status)) {
    5799           0 :                 printf("[11] close failed (%s)\n", nt_errstr(status));
    5800           0 :                 goto fail;
    5801             :         }
    5802             : 
    5803             :         /* Now try open for delete access. */
    5804           5 :         status = cli_ntcreate(cli1, fname, 0,
    5805             :                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
    5806             :                              0,
    5807             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5808             :                              FILE_OPEN, 0, 0, &fnum1, NULL);
    5809           5 :         if (!NT_STATUS_IS_OK(status)) {
    5810           0 :                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
    5811           0 :                 goto fail;
    5812             :         }
    5813             : 
    5814           5 :         cli_close(cli1, fnum1);
    5815             : 
    5816           5 :         printf("eleventh delete on close test succeeded.\n");
    5817             : 
    5818             :         /*
    5819             :          * Test 12
    5820             :          * like test 4 but with initial delete on close
    5821             :          */
    5822             : 
    5823           5 :         cli_setatr(cli1, fname, 0, 0);
    5824           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5825             : 
    5826           5 :         status = cli_ntcreate(cli1, fname, 0,
    5827             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5828             :                               FILE_ATTRIBUTE_NORMAL,
    5829             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5830             :                               FILE_OVERWRITE_IF,
    5831             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5832           5 :         if (!NT_STATUS_IS_OK(status)) {
    5833           0 :                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5834           0 :                 goto fail;
    5835             :         }
    5836             : 
    5837           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5838             :                               FILE_ATTRIBUTE_NORMAL,
    5839             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5840             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5841           5 :         if (!NT_STATUS_IS_OK(status)) {
    5842           0 :                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
    5843           0 :                 goto fail;
    5844             :         }
    5845             : 
    5846           5 :         status = cli_close(cli1, fnum2);
    5847           5 :         if (!NT_STATUS_IS_OK(status)) {
    5848           0 :                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
    5849           0 :                 goto fail;
    5850             :         }
    5851             : 
    5852           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5853           5 :         if (!NT_STATUS_IS_OK(status)) {
    5854           0 :                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5855           0 :                 goto fail;
    5856             :         }
    5857             : 
    5858             :         /* This should fail - no more opens once delete on close set. */
    5859           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5860             :                               FILE_ATTRIBUTE_NORMAL,
    5861             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5862             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5863           5 :         if (NT_STATUS_IS_OK(status)) {
    5864           0 :                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
    5865           0 :                 goto fail;
    5866             :         }
    5867             : 
    5868           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5869           5 :         if (!NT_STATUS_IS_OK(status)) {
    5870           0 :                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
    5871           0 :                 goto fail;
    5872             :         }
    5873             : 
    5874           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5875             :                               FILE_ATTRIBUTE_NORMAL,
    5876             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5877             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5878           5 :         if (!NT_STATUS_IS_OK(status)) {
    5879           0 :                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
    5880           0 :                 goto fail;
    5881             :         }
    5882             : 
    5883           5 :         status = cli_close(cli1, fnum2);
    5884           5 :         if (!NT_STATUS_IS_OK(status)) {
    5885           0 :                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
    5886           0 :                 goto fail;
    5887             :         }
    5888             : 
    5889           5 :         status = cli_close(cli1, fnum1);
    5890           5 :         if (!NT_STATUS_IS_OK(status)) {
    5891           0 :                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
    5892           0 :                 goto fail;
    5893             :         }
    5894             : 
    5895             :         /*
    5896             :          * setting delete on close on the handle does
    5897             :          * not unset the initial delete on close...
    5898             :          */
    5899           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5900             :                               FILE_ATTRIBUTE_NORMAL,
    5901             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5902             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5903           5 :         if (NT_STATUS_IS_OK(status)) {
    5904           0 :                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
    5905           0 :                 goto fail;
    5906           5 :         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5907           0 :                 printf("ntcreate returned %s, expected "
    5908             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
    5909             :                        nt_errstr(status));
    5910           0 :                 goto fail;
    5911             :         }
    5912             : 
    5913           5 :         printf("twelfth delete on close test succeeded.\n");
    5914             : 
    5915             : 
    5916           5 :         printf("finished delete test\n");
    5917             : 
    5918           5 :         correct = true;
    5919             : 
    5920           5 :   fail:
    5921             :         /* FIXME: This will crash if we aborted before cli2 got
    5922             :          * initialized, because these functions don't handle
    5923             :          * uninitialized connections. */
    5924             : 
    5925           5 :         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
    5926           5 :         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
    5927           5 :         cli_setatr(cli1, fname, 0, 0);
    5928           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5929             : 
    5930           5 :         if (cli1 && !torture_close_connection(cli1)) {
    5931           0 :                 correct = False;
    5932             :         }
    5933           5 :         if (cli2 && !torture_close_connection(cli2)) {
    5934           0 :                 correct = False;
    5935             :         }
    5936           5 :         return correct;
    5937             : }
    5938             : 
    5939             : struct delete_stream_state {
    5940             :         bool closed;
    5941             : };
    5942             : 
    5943             : static void delete_stream_unlinked(struct tevent_req *subreq);
    5944             : static void delete_stream_closed(struct tevent_req *subreq);
    5945             : 
    5946           5 : static struct tevent_req *delete_stream_send(
    5947             :         TALLOC_CTX *mem_ctx,
    5948             :         struct tevent_context *ev,
    5949             :         struct cli_state *cli,
    5950             :         const char *base_fname,
    5951             :         uint16_t stream_fnum)
    5952             : {
    5953           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    5954           5 :         struct delete_stream_state *state = NULL;
    5955             : 
    5956           5 :         req = tevent_req_create(
    5957             :                 mem_ctx, &state, struct delete_stream_state);
    5958           5 :         if (req == NULL) {
    5959           0 :                 return NULL;
    5960             :         }
    5961             : 
    5962           5 :         subreq = cli_unlink_send(
    5963             :                 state,
    5964             :                 ev,
    5965             :                 cli,
    5966             :                 base_fname,
    5967             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5968           5 :         if (tevent_req_nomem(subreq, req)) {
    5969           0 :                 return tevent_req_post(req, ev);
    5970             :         }
    5971           5 :         tevent_req_set_callback(subreq, delete_stream_unlinked, req);
    5972             : 
    5973           5 :         subreq = cli_close_send(state, ev, cli, stream_fnum, 0);
    5974           5 :         if (tevent_req_nomem(subreq, req)) {
    5975           0 :                 return tevent_req_post(req, ev);
    5976             :         }
    5977           5 :         tevent_req_set_callback(subreq, delete_stream_closed, req);
    5978             : 
    5979           5 :         return req;
    5980             : }
    5981             : 
    5982           5 : static void delete_stream_unlinked(struct tevent_req *subreq)
    5983             : {
    5984           5 :         struct tevent_req *req = tevent_req_callback_data(
    5985             :                 subreq, struct tevent_req);
    5986           5 :         struct delete_stream_state *state = tevent_req_data(
    5987             :                 req, struct delete_stream_state);
    5988           0 :         NTSTATUS status;
    5989             : 
    5990           5 :         status = cli_unlink_recv(subreq);
    5991           5 :         TALLOC_FREE(subreq);
    5992           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    5993           0 :                 printf("cli_unlink returned %s\n",
    5994             :                        nt_errstr(status));
    5995           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5996           0 :                 return;
    5997             :         }
    5998           5 :         if (!state->closed) {
    5999             :                 /* close reply should have come in first */
    6000           0 :                 printf("Not closed\n");
    6001           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    6002           0 :                 return;
    6003             :         }
    6004           5 :         tevent_req_done(req);
    6005             : }
    6006             : 
    6007           5 : static void delete_stream_closed(struct tevent_req *subreq)
    6008             : {
    6009           5 :         struct tevent_req *req = tevent_req_callback_data(
    6010             :                 subreq, struct tevent_req);
    6011           5 :         struct delete_stream_state *state = tevent_req_data(
    6012             :                 req, struct delete_stream_state);
    6013           0 :         NTSTATUS status;
    6014             : 
    6015           5 :         status = cli_close_recv(subreq);
    6016           5 :         TALLOC_FREE(subreq);
    6017           5 :         if (tevent_req_nterror(req, status)) {
    6018           0 :                 return;
    6019             :         }
    6020             :         /* also waiting for the unlink to come back */
    6021           5 :         state->closed = true;
    6022             : }
    6023             : 
    6024           5 : static NTSTATUS delete_stream_recv(struct tevent_req *req)
    6025             : {
    6026           5 :         return tevent_req_simple_recv_ntstatus(req);
    6027             : }
    6028             : 
    6029           5 : static bool run_delete_stream(int dummy)
    6030             : {
    6031           5 :         struct tevent_context *ev = NULL;
    6032           5 :         struct tevent_req *req = NULL;
    6033           5 :         struct cli_state *cli = NULL;
    6034           5 :         const char fname[] = "delete_stream";
    6035           5 :         const char fname_stream[] = "delete_stream:Zone.Identifier:$DATA";
    6036           0 :         uint16_t fnum1, fnum2;
    6037           0 :         NTSTATUS status;
    6038           0 :         bool ok;
    6039             : 
    6040           5 :         printf("Starting stream delete test\n");
    6041             : 
    6042           5 :         ok = torture_open_connection(&cli, 0);
    6043           5 :         if (!ok) {
    6044           0 :                 return false;
    6045             :         }
    6046             : 
    6047           5 :         cli_setatr(cli, fname, 0, 0);
    6048           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6049             : 
    6050             :         /* Create the file. */
    6051           5 :         status = cli_ntcreate(
    6052             :                 cli,
    6053             :                 fname,
    6054             :                 0,
    6055             :                 READ_CONTROL_ACCESS,
    6056             :                 0,
    6057             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6058             :                 FILE_CREATE,
    6059             :                 0x0,
    6060             :                 0x0,
    6061             :                 &fnum1,
    6062             :                 NULL);
    6063           5 :         if (!NT_STATUS_IS_OK(status)) {
    6064           0 :                 d_fprintf(stderr,
    6065             :                           "cli_ntcreate of %s failed (%s)\n",
    6066             :                           fname,
    6067             :                           nt_errstr(status));
    6068           0 :                 return false;
    6069             :         }
    6070           5 :         status = cli_close(cli, fnum1);
    6071           5 :         if (!NT_STATUS_IS_OK(status)) {
    6072           0 :                 d_fprintf(stderr,
    6073             :                           "cli_close of %s failed (%s)\n",
    6074             :                           fname,
    6075             :                           nt_errstr(status));
    6076           0 :                 return false;
    6077             :         }
    6078             : 
    6079             :         /* Now create the stream. */
    6080           5 :         status = cli_ntcreate(
    6081             :                 cli,
    6082             :                 fname_stream,
    6083             :                 0,
    6084             :                 FILE_WRITE_DATA,
    6085             :                 0,
    6086             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6087             :                 FILE_CREATE,
    6088             :                 0x0,
    6089             :                 0x0,
    6090             :                 &fnum1,
    6091             :                 NULL);
    6092             : 
    6093           5 :         if (!NT_STATUS_IS_OK(status)) {
    6094           0 :                 d_fprintf(stderr,
    6095             :                           "cli_ntcreate of %s failed (%s)\n",
    6096             :                           fname_stream,
    6097             :                           nt_errstr(status));
    6098           0 :                 return false;
    6099             :         }
    6100             : 
    6101             :         /* open it a second time */
    6102             : 
    6103           5 :         status = cli_ntcreate(
    6104             :                 cli,
    6105             :                 fname_stream,
    6106             :                 0,
    6107             :                 FILE_WRITE_DATA,
    6108             :                 0,
    6109             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6110             :                 FILE_OPEN,
    6111             :                 0x0,
    6112             :                 0x0,
    6113             :                 &fnum2,
    6114             :                 NULL);
    6115             : 
    6116           5 :         if (!NT_STATUS_IS_OK(status)) {
    6117           0 :                 d_fprintf(stderr,
    6118             :                           "2nd cli_ntcreate of %s failed (%s)\n",
    6119             :                           fname_stream,
    6120             :                           nt_errstr(status));
    6121           0 :                 return false;
    6122             :         }
    6123             : 
    6124           5 :         ev = samba_tevent_context_init(talloc_tos());
    6125           5 :         if (ev == NULL) {
    6126           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    6127           0 :                 return false;
    6128             :         }
    6129             : 
    6130           5 :         req = delete_stream_send(ev, ev, cli, fname, fnum1);
    6131           5 :         if (req == NULL) {
    6132           0 :                 d_fprintf(stderr, "delete_stream_send failed\n");
    6133           0 :                 return false;
    6134             :         }
    6135             : 
    6136           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    6137           5 :         if (!ok) {
    6138           0 :                 d_fprintf(stderr,
    6139             :                           "tevent_req_poll_ntstatus failed: %s\n",
    6140             :                           nt_errstr(status));
    6141           0 :                 return false;
    6142             :         }
    6143             : 
    6144           5 :         status = delete_stream_recv(req);
    6145           5 :         TALLOC_FREE(req);
    6146           5 :         if (!NT_STATUS_IS_OK(status)) {
    6147           0 :                 d_fprintf(stderr,
    6148             :                           "delete_stream failed: %s\n",
    6149             :                           nt_errstr(status));
    6150           0 :                 return false;
    6151             :         }
    6152             : 
    6153           5 :         status = cli_close(cli, fnum2);
    6154           5 :         if (!NT_STATUS_IS_OK(status)) {
    6155           0 :                 d_fprintf(stderr,
    6156             :                           "close failed: %s\n",
    6157             :                           nt_errstr(status));
    6158           0 :                 return false;
    6159             :         }
    6160             : 
    6161           5 :         status = cli_unlink(
    6162             :                 cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6163           5 :         if (!NT_STATUS_IS_OK(status)) {
    6164           0 :                 d_fprintf(stderr,
    6165             :                           "unlink failed: %s\n",
    6166             :                           nt_errstr(status));
    6167           0 :                 return false;
    6168             :         }
    6169             : 
    6170           5 :         return true;
    6171             : }
    6172             : 
    6173             : /*
    6174             :   Exercise delete on close semantics - use on the PRINT1 share in torture
    6175             :   testing.
    6176             :  */
    6177           2 : static bool run_delete_print_test(int dummy)
    6178             : {
    6179           2 :         struct cli_state *cli1 = NULL;
    6180           2 :         const char *fname = "print_delete.file";
    6181           2 :         uint16_t fnum1 = (uint16_t)-1;
    6182           2 :         bool correct = false;
    6183           2 :         const char *buf = "print file data\n";
    6184           0 :         NTSTATUS status;
    6185             : 
    6186           2 :         printf("starting print delete test\n");
    6187             : 
    6188           2 :         if (!torture_open_connection(&cli1, 0)) {
    6189           0 :                 return false;
    6190             :         }
    6191             : 
    6192           2 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    6193             : 
    6194           2 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    6195             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    6196             :                               0, 0, &fnum1, NULL);
    6197           2 :         if (!NT_STATUS_IS_OK(status)) {
    6198           0 :                 printf("open of %s failed (%s)\n",
    6199             :                         fname,
    6200             :                         nt_errstr(status));
    6201           0 :                 goto fail;
    6202             :         }
    6203             : 
    6204           2 :         status = cli_writeall(cli1,
    6205             :                         fnum1,
    6206             :                         0,
    6207             :                         (const uint8_t *)buf,
    6208             :                         0, /* offset */
    6209             :                         strlen(buf), /* size */
    6210             :                         NULL);
    6211           2 :         if (!NT_STATUS_IS_OK(status)) {
    6212           0 :                 printf("writing print file data failed (%s)\n",
    6213             :                         nt_errstr(status));
    6214           0 :                 goto fail;
    6215             :         }
    6216             : 
    6217           2 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    6218           2 :         if (!NT_STATUS_IS_OK(status)) {
    6219           0 :                 printf("setting delete_on_close failed (%s)\n",
    6220             :                         nt_errstr(status));
    6221           0 :                 goto fail;
    6222             :         }
    6223             : 
    6224           2 :         status = cli_close(cli1, fnum1);
    6225           2 :         if (!NT_STATUS_IS_OK(status)) {
    6226           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    6227           0 :                 goto fail;
    6228             :         }
    6229             : 
    6230           2 :         printf("finished print delete test\n");
    6231             : 
    6232           2 :         correct = true;
    6233             : 
    6234           2 :   fail:
    6235             : 
    6236           2 :         if (fnum1 != (uint16_t)-1) {
    6237           2 :                 cli_close(cli1, fnum1);
    6238             :         }
    6239             : 
    6240           2 :         if (cli1 && !torture_close_connection(cli1)) {
    6241           0 :                 correct = false;
    6242             :         }
    6243           2 :         return correct;
    6244             : }
    6245             : 
    6246           4 : static bool run_deletetest_ln(int dummy)
    6247             : {
    6248           0 :         struct cli_state *cli;
    6249           4 :         const char *fname = "\\delete1";
    6250           4 :         const char *fname_ln = "\\delete1_ln";
    6251           0 :         uint16_t fnum;
    6252           0 :         uint16_t fnum1;
    6253           0 :         NTSTATUS status;
    6254           4 :         bool correct = true;
    6255           0 :         time_t t;
    6256             : 
    6257           4 :         printf("starting deletetest-ln\n");
    6258             : 
    6259           4 :         if (!torture_open_connection(&cli, 0)) {
    6260           0 :                 return false;
    6261             :         }
    6262             : 
    6263           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6264           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6265             : 
    6266           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6267             : 
    6268             :         /* Create the file. */
    6269           4 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6270           4 :         if (!NT_STATUS_IS_OK(status)) {
    6271           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    6272           0 :                 return false;
    6273             :         }
    6274             : 
    6275           4 :         status = cli_close(cli, fnum);
    6276           4 :         if (!NT_STATUS_IS_OK(status)) {
    6277           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    6278           0 :                 return false;
    6279             :         }
    6280             : 
    6281             :         /* Now create a hardlink. */
    6282           4 :         status = cli_hardlink(cli, fname, fname_ln);
    6283           4 :         if (!NT_STATUS_IS_OK(status)) {
    6284           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    6285           0 :                 return false;
    6286             :         }
    6287             : 
    6288             :         /* Open the original file. */
    6289           4 :         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
    6290             :                         FILE_ATTRIBUTE_NORMAL,
    6291             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6292             :                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
    6293           4 :         if (!NT_STATUS_IS_OK(status)) {
    6294           0 :                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
    6295           0 :                 return false;
    6296             :         }
    6297             : 
    6298             :         /* Unlink the hard link path. */
    6299           4 :         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
    6300             :                         FILE_ATTRIBUTE_NORMAL,
    6301             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6302             :                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
    6303           4 :         if (!NT_STATUS_IS_OK(status)) {
    6304           0 :                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
    6305           0 :                 return false;
    6306             :         }
    6307           4 :         status = cli_nt_delete_on_close(cli, fnum1, true);
    6308           4 :         if (!NT_STATUS_IS_OK(status)) {
    6309           0 :                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
    6310             :                         __location__, fname_ln, nt_errstr(status));
    6311           0 :                 return false;
    6312             :         }
    6313             : 
    6314           4 :         status = cli_close(cli, fnum1);
    6315           4 :         if (!NT_STATUS_IS_OK(status)) {
    6316           0 :                 printf("close %s failed (%s)\n",
    6317             :                         fname_ln, nt_errstr(status));
    6318           0 :                 return false;
    6319             :         }
    6320             : 
    6321           4 :         status = cli_close(cli, fnum);
    6322           4 :         if (!NT_STATUS_IS_OK(status)) {
    6323           0 :                 printf("close %s failed (%s)\n",
    6324             :                         fname, nt_errstr(status));
    6325           0 :                 return false;
    6326             :         }
    6327             : 
    6328             :         /* Ensure the original file is still there. */
    6329           4 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    6330           4 :         if (!NT_STATUS_IS_OK(status)) {
    6331           0 :                 printf("%s getatr on file %s failed (%s)\n",
    6332             :                         __location__,
    6333             :                         fname,
    6334             :                         nt_errstr(status));
    6335           0 :                 correct = False;
    6336             :         }
    6337             : 
    6338             :         /* Ensure the link path is gone. */
    6339           4 :         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
    6340           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    6341           0 :                 printf("%s, getatr for file %s returned wrong error code %s "
    6342             :                         "- should have been deleted\n",
    6343             :                         __location__,
    6344             :                         fname_ln, nt_errstr(status));
    6345           0 :                 correct = False;
    6346             :         }
    6347             : 
    6348           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6349           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6350             : 
    6351           4 :         if (!torture_close_connection(cli)) {
    6352           0 :                 correct = false;
    6353             :         }
    6354             : 
    6355           4 :         printf("finished deletetest-ln\n");
    6356             : 
    6357           4 :         return correct;
    6358             : }
    6359             : 
    6360             : /*
    6361             :   print out server properties
    6362             :  */
    6363           5 : static bool run_properties(int dummy)
    6364             : {
    6365           0 :         struct cli_state *cli;
    6366           5 :         bool correct = True;
    6367             : 
    6368           5 :         printf("starting properties test\n");
    6369             : 
    6370           5 :         ZERO_STRUCT(cli);
    6371             : 
    6372           5 :         if (!torture_open_connection(&cli, 0)) {
    6373           0 :                 return False;
    6374             :         }
    6375             : 
    6376           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6377             : 
    6378           5 :         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
    6379             : 
    6380           5 :         if (!torture_close_connection(cli)) {
    6381           0 :                 correct = False;
    6382             :         }
    6383             : 
    6384           5 :         return correct;
    6385             : }
    6386             : 
    6387             : 
    6388             : 
    6389             : /* FIRST_DESIRED_ACCESS   0xf019f */
    6390             : #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
    6391             :                                FILE_READ_EA|                           /* 0xf */ \
    6392             :                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
    6393             :                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
    6394             :                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
    6395             :                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
    6396             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    6397             : #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6398             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6399             :                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
    6400             : 
    6401             : #if 0
    6402             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6403             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6404             :                                FILE_READ_DATA|\
    6405             :                                WRITE_OWNER_ACCESS                      /* */
    6406             : #endif
    6407             : 
    6408             : /*
    6409             :   Test ntcreate calls made by xcopy
    6410             :  */
    6411           5 : static bool run_xcopy(int dummy)
    6412             : {
    6413           0 :         static struct cli_state *cli1;
    6414           5 :         const char *fname = "\\test.txt";
    6415           5 :         bool correct = True;
    6416           0 :         uint16_t fnum1, fnum2;
    6417           0 :         NTSTATUS status;
    6418             : 
    6419           5 :         printf("starting xcopy test\n");
    6420             : 
    6421           5 :         if (!torture_open_connection(&cli1, 0)) {
    6422           0 :                 return False;
    6423             :         }
    6424             : 
    6425           5 :         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
    6426             :                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
    6427             :                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
    6428           5 :         if (!NT_STATUS_IS_OK(status)) {
    6429           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6430           0 :                 return False;
    6431             :         }
    6432             : 
    6433           5 :         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
    6434             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6435             :                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
    6436           5 :         if (!NT_STATUS_IS_OK(status)) {
    6437           0 :                 printf("second open failed - %s\n", nt_errstr(status));
    6438           0 :                 return False;
    6439             :         }
    6440             : 
    6441           5 :         if (!torture_close_connection(cli1)) {
    6442           0 :                 correct = False;
    6443             :         }
    6444             : 
    6445           5 :         return correct;
    6446             : }
    6447             : 
    6448             : /*
    6449             :   Test rename on files open with share delete and no share delete.
    6450             :  */
    6451           5 : static bool run_rename(int dummy)
    6452             : {
    6453           0 :         static struct cli_state *cli1;
    6454           5 :         const char *fname = "\\test.txt";
    6455           5 :         const char *fname1 = "\\test1.txt";
    6456           5 :         bool correct = True;
    6457           0 :         uint16_t fnum1;
    6458           0 :         uint32_t attr;
    6459           0 :         NTSTATUS status;
    6460             : 
    6461           5 :         printf("starting rename test\n");
    6462             : 
    6463           5 :         if (!torture_open_connection(&cli1, 0)) {
    6464           0 :                 return False;
    6465             :         }
    6466             : 
    6467           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6468           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6469             : 
    6470           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6471             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    6472             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6473           5 :         if (!NT_STATUS_IS_OK(status)) {
    6474           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6475           0 :                 return False;
    6476             :         }
    6477             : 
    6478           5 :         status = cli_rename(cli1, fname, fname1, false);
    6479           5 :         if (!NT_STATUS_IS_OK(status)) {
    6480           5 :                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
    6481             :         } else {
    6482           0 :                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
    6483           0 :                 correct = False;
    6484             :         }
    6485             : 
    6486           5 :         status = cli_close(cli1, fnum1);
    6487           5 :         if (!NT_STATUS_IS_OK(status)) {
    6488           0 :                 printf("close - 1 failed (%s)\n", nt_errstr(status));
    6489           0 :                 return False;
    6490             :         }
    6491             : 
    6492           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6493           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6494           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
    6495             : #if 0
    6496             :                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
    6497             : #else
    6498             :                               FILE_SHARE_DELETE|FILE_SHARE_READ,
    6499             : #endif
    6500             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6501           5 :         if (!NT_STATUS_IS_OK(status)) {
    6502           0 :                 printf("Second open failed - %s\n", nt_errstr(status));
    6503           0 :                 return False;
    6504             :         }
    6505             : 
    6506           5 :         status = cli_rename(cli1, fname, fname1, false);
    6507           5 :         if (!NT_STATUS_IS_OK(status)) {
    6508           0 :                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
    6509           0 :                 correct = False;
    6510             :         } else {
    6511           5 :                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
    6512             :         }
    6513             : 
    6514           5 :         status = cli_close(cli1, fnum1);
    6515           5 :         if (!NT_STATUS_IS_OK(status)) {
    6516           0 :                 printf("close - 2 failed (%s)\n", nt_errstr(status));
    6517           0 :                 return False;
    6518             :         }
    6519             : 
    6520           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6521           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6522             : 
    6523           5 :         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
    6524             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    6525             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6526           5 :         if (!NT_STATUS_IS_OK(status)) {
    6527           0 :                 printf("Third open failed - %s\n", nt_errstr(status));
    6528           0 :                 return False;
    6529             :         }
    6530             : 
    6531             : 
    6532           5 :         status = cli_rename(cli1, fname, fname1, false);
    6533           5 :         if (!NT_STATUS_IS_OK(status)) {
    6534           0 :                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
    6535           0 :                 correct = False;
    6536             :         } else {
    6537           5 :                 printf("Third rename succeeded (SHARE_NONE)\n");
    6538             :         }
    6539             : 
    6540           5 :         status = cli_close(cli1, fnum1);
    6541           5 :         if (!NT_STATUS_IS_OK(status)) {
    6542           0 :                 printf("close - 3 failed (%s)\n", nt_errstr(status));
    6543           0 :                 return False;
    6544             :         }
    6545             : 
    6546           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6547           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6548             : 
    6549             :         /*----*/
    6550             : 
    6551           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6552             :                               FILE_ATTRIBUTE_NORMAL,
    6553             :                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    6554             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6555           5 :         if (!NT_STATUS_IS_OK(status)) {
    6556           0 :                 printf("Fourth open failed - %s\n", nt_errstr(status));
    6557           0 :                 return False;
    6558             :         }
    6559             : 
    6560           5 :         status = cli_rename(cli1, fname, fname1, false);
    6561           5 :         if (!NT_STATUS_IS_OK(status)) {
    6562           5 :                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
    6563             :         } else {
    6564           0 :                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
    6565           0 :                 correct = False;
    6566             :         }
    6567             : 
    6568           5 :         status = cli_close(cli1, fnum1);
    6569           5 :         if (!NT_STATUS_IS_OK(status)) {
    6570           0 :                 printf("close - 4 failed (%s)\n", nt_errstr(status));
    6571           0 :                 return False;
    6572             :         }
    6573             : 
    6574           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6575           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6576             : 
    6577             :         /*--*/
    6578             : 
    6579           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6580             :                          FILE_ATTRIBUTE_NORMAL,
    6581             :                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    6582             :                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6583           5 :         if (!NT_STATUS_IS_OK(status)) {
    6584           0 :                 printf("Fifth open failed - %s\n", nt_errstr(status));
    6585           0 :                 return False;
    6586             :         }
    6587             : 
    6588           5 :         status = cli_rename(cli1, fname, fname1, false);
    6589           5 :         if (!NT_STATUS_IS_OK(status)) {
    6590           0 :                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
    6591           0 :                 correct = False;
    6592             :         } else {
    6593           5 :                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
    6594             :         }
    6595             : 
    6596             :         /*--*/
    6597           5 :         status = cli_close(cli1, fnum1);
    6598           5 :         if (!NT_STATUS_IS_OK(status)) {
    6599           0 :                 printf("close - 5 failed (%s)\n", nt_errstr(status));
    6600           0 :                 return False;
    6601             :         }
    6602             : 
    6603             :         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
    6604           5 :         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
    6605           5 :         if (!NT_STATUS_IS_OK(status)) {
    6606           0 :                 printf("getatr on file %s failed - %s ! \n",
    6607             :                         fname1, nt_errstr(status));
    6608           0 :                 correct = False;
    6609             :         } else {
    6610           5 :                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
    6611           0 :                         printf("Renamed file %s has wrong attr 0x%x "
    6612             :                                 "(should be 0x%x)\n",
    6613             :                                 fname1,
    6614             :                                 attr,
    6615             :                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
    6616           0 :                         correct = False;
    6617             :                 } else {
    6618           5 :                         printf("Renamed file %s has archive bit set\n", fname1);
    6619             :                 }
    6620             :         }
    6621             : 
    6622           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6623           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6624             : 
    6625           5 :         if (!torture_close_connection(cli1)) {
    6626           0 :                 correct = False;
    6627             :         }
    6628             : 
    6629           5 :         return correct;
    6630             : }
    6631             : 
    6632             : /*
    6633             :   Test rename into a directory with an ACL denying it.
    6634             :  */
    6635           4 : static bool run_rename_access(int dummy)
    6636             : {
    6637           0 :         static struct cli_state *cli = NULL;
    6638           0 :         static struct cli_state *posix_cli = NULL;
    6639           4 :         const char *src = "test.txt";
    6640           4 :         const char *dname = "dir";
    6641           4 :         const char *dst = "dir\\test.txt";
    6642           4 :         const char *dsrc = "test.dir";
    6643           4 :         const char *ddst = "dir\\test.dir";
    6644           4 :         uint16_t fnum = (uint16_t)-1;
    6645           4 :         struct security_descriptor *sd = NULL;
    6646           4 :         struct security_descriptor *newsd = NULL;
    6647           0 :         NTSTATUS status;
    6648           4 :         TALLOC_CTX *frame = NULL;
    6649             : 
    6650           4 :         frame = talloc_stackframe();
    6651           4 :         printf("starting rename access test\n");
    6652             : 
    6653             :         /* Windows connection. */
    6654           4 :         if (!torture_open_connection(&cli, 0)) {
    6655           0 :                 goto fail;
    6656             :         }
    6657             : 
    6658           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6659             : 
    6660             :         /* Posix connection. */
    6661           4 :         if (!torture_open_connection(&posix_cli, 0)) {
    6662           0 :                 goto fail;
    6663             :         }
    6664             : 
    6665           4 :         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
    6666             : 
    6667           4 :         status = torture_setup_unix_extensions(posix_cli);
    6668           4 :         if (!NT_STATUS_IS_OK(status)) {
    6669           0 :                 goto fail;
    6670             :         }
    6671             : 
    6672             :         /* Start with a clean slate. */
    6673           4 :         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6674           4 :         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6675           4 :         cli_rmdir(cli, dsrc);
    6676           4 :         cli_rmdir(cli, ddst);
    6677           4 :         cli_rmdir(cli, dname);
    6678             : 
    6679             :         /*
    6680             :          * Setup the destination directory with a DENY ACE to
    6681             :          * prevent new files within it.
    6682             :          */
    6683           4 :         status = cli_ntcreate(cli,
    6684             :                                 dname,
    6685             :                                 0,
    6686             :                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
    6687             :                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
    6688             :                                         WRITE_OWNER_ACCESS,
    6689             :                                 FILE_ATTRIBUTE_DIRECTORY,
    6690             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6691             :                                 FILE_CREATE,
    6692             :                                 FILE_DIRECTORY_FILE,
    6693             :                                 0,
    6694             :                                 &fnum,
    6695             :                                 NULL);
    6696           4 :         if (!NT_STATUS_IS_OK(status)) {
    6697           0 :                 printf("Create of %s - %s\n", dname, nt_errstr(status));
    6698           0 :                 goto fail;
    6699             :         }
    6700             : 
    6701           4 :         status = cli_query_secdesc(cli,
    6702             :                                 fnum,
    6703             :                                 frame,
    6704             :                                 &sd);
    6705           4 :         if (!NT_STATUS_IS_OK(status)) {
    6706           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6707             :                         dname, nt_errstr(status));
    6708           0 :                 goto fail;
    6709             :         }
    6710             : 
    6711           4 :         newsd = security_descriptor_dacl_create(frame,
    6712             :                                         0,
    6713             :                                         NULL,
    6714             :                                         NULL,
    6715             :                                         SID_WORLD,
    6716             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6717             :                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
    6718             :                                         0,
    6719             :                                         NULL);
    6720           4 :         if (newsd == NULL) {
    6721           0 :                 goto fail;
    6722             :         }
    6723           8 :         sd->dacl = security_acl_concatenate(frame,
    6724           4 :                                         newsd->dacl,
    6725           4 :                                         sd->dacl);
    6726           4 :         if (sd->dacl == NULL) {
    6727           0 :                 goto fail;
    6728             :         }
    6729           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6730           4 :         if (!NT_STATUS_IS_OK(status)) {
    6731           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6732             :                         dname, nt_errstr(status));
    6733           0 :                 goto fail;
    6734             :         }
    6735           4 :         status = cli_close(cli, fnum);
    6736           4 :         if (!NT_STATUS_IS_OK(status)) {
    6737           0 :                 printf("close failed for %s (%s)\n",
    6738             :                         dname, nt_errstr(status));
    6739           0 :                 goto fail;
    6740             :         }
    6741             :         /* Now go around the back and chmod to 777 via POSIX. */
    6742           4 :         status = cli_posix_chmod(posix_cli, dname, 0777);
    6743           4 :         if (!NT_STATUS_IS_OK(status)) {
    6744           0 :                 printf("cli_posix_chmod failed for %s (%s)\n",
    6745             :                         dname, nt_errstr(status));
    6746           0 :                 goto fail;
    6747             :         }
    6748             : 
    6749             :         /* Check we can't create a file within dname via Windows. */
    6750           4 :         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6751           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6752           0 :                 cli_close(posix_cli, fnum);
    6753           0 :                 printf("Create of %s should be ACCESS denied, was %s\n",
    6754             :                         dst, nt_errstr(status));
    6755           0 :                 goto fail;
    6756             :         }
    6757             : 
    6758             :         /* Make the sample file/directory. */
    6759           4 :         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6760           4 :         if (!NT_STATUS_IS_OK(status)) {
    6761           0 :                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
    6762           0 :                 goto fail;
    6763             :         }
    6764           4 :         status = cli_close(cli, fnum);
    6765           4 :         if (!NT_STATUS_IS_OK(status)) {
    6766           0 :                 printf("cli_close failed (%s)\n", nt_errstr(status));
    6767           0 :                 goto fail;
    6768             :         }
    6769             : 
    6770           4 :         status = cli_mkdir(cli, dsrc);
    6771           4 :         if (!NT_STATUS_IS_OK(status)) {
    6772           0 :                 printf("cli_mkdir of %s failed (%s)\n",
    6773             :                         dsrc, nt_errstr(status));
    6774           0 :                 goto fail;
    6775             :         }
    6776             : 
    6777             :         /*
    6778             :          * OK - renames of the new file and directory into the
    6779             :          * dst directory should fail.
    6780             :          */
    6781             : 
    6782           4 :         status = cli_rename(cli, src, dst, false);
    6783           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6784           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6785             :                         src, dst, nt_errstr(status));
    6786           0 :                 goto fail;
    6787             :         }
    6788           4 :         status = cli_rename(cli, dsrc, ddst, false);
    6789           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6790           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6791             :                         src, dst, nt_errstr(status));
    6792           0 :                 goto fail;
    6793             :         }
    6794             : 
    6795           4 :         TALLOC_FREE(frame);
    6796           4 :         return true;
    6797             : 
    6798           0 :   fail:
    6799             : 
    6800           0 :         if (posix_cli) {
    6801           0 :                 torture_close_connection(posix_cli);
    6802             :         }
    6803             : 
    6804           0 :         if (cli) {
    6805           0 :                 if (fnum != (uint16_t)-1) {
    6806           0 :                         cli_close(cli, fnum);
    6807             :                 }
    6808           0 :                 cli_unlink(cli, src,
    6809             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6810           0 :                 cli_unlink(cli, dst,
    6811             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6812           0 :                 cli_rmdir(cli, dsrc);
    6813           0 :                 cli_rmdir(cli, ddst);
    6814           0 :                 cli_rmdir(cli, dname);
    6815             : 
    6816           0 :                 torture_close_connection(cli);
    6817             :         }
    6818             : 
    6819           0 :         TALLOC_FREE(frame);
    6820           0 :         return false;
    6821             : }
    6822             : 
    6823             : /*
    6824             :   Test owner rights ACE.
    6825             :  */
    6826           4 : static bool run_owner_rights(int dummy)
    6827             : {
    6828           0 :         static struct cli_state *cli = NULL;
    6829           4 :         const char *fname = "owner_rights.txt";
    6830           4 :         uint16_t fnum = (uint16_t)-1;
    6831           4 :         struct security_descriptor *sd = NULL;
    6832           4 :         struct security_descriptor *newsd = NULL;
    6833           0 :         NTSTATUS status;
    6834           4 :         TALLOC_CTX *frame = NULL;
    6835             : 
    6836           4 :         frame = talloc_stackframe();
    6837           4 :         printf("starting owner rights test\n");
    6838             : 
    6839             :         /* Windows connection. */
    6840           4 :         if (!torture_open_connection(&cli, 0)) {
    6841           0 :                 goto fail;
    6842             :         }
    6843             : 
    6844           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6845             : 
    6846             :         /* Start with a clean slate. */
    6847           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6848             : 
    6849             :         /* Create the test file. */
    6850             :         /* Now try and open for read and write-dac. */
    6851           4 :         status = cli_ntcreate(cli,
    6852             :                                 fname,
    6853             :                                 0,
    6854             :                                 GENERIC_ALL_ACCESS,
    6855             :                                 FILE_ATTRIBUTE_NORMAL,
    6856             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6857             :                                         FILE_SHARE_DELETE,
    6858             :                                 FILE_CREATE,
    6859             :                                 0,
    6860             :                                 0,
    6861             :                                 &fnum,
    6862             :                                 NULL);
    6863           4 :         if (!NT_STATUS_IS_OK(status)) {
    6864           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6865           0 :                 goto fail;
    6866             :         }
    6867             : 
    6868             :         /* Get the original SD. */
    6869           4 :         status = cli_query_secdesc(cli,
    6870             :                                 fnum,
    6871             :                                 frame,
    6872             :                                 &sd);
    6873           4 :         if (!NT_STATUS_IS_OK(status)) {
    6874           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6875             :                         fname, nt_errstr(status));
    6876           0 :                 goto fail;
    6877             :         }
    6878             : 
    6879             :         /*
    6880             :          * Add an "owner-rights" ACE denying WRITE_DATA,
    6881             :          * and an "owner-rights" ACE allowing READ_DATA.
    6882             :          */
    6883             : 
    6884           4 :         newsd = security_descriptor_dacl_create(frame,
    6885             :                                         0,
    6886             :                                         NULL,
    6887             :                                         NULL,
    6888             :                                         SID_OWNER_RIGHTS,
    6889             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6890             :                                         FILE_WRITE_DATA,
    6891             :                                         0,
    6892             :                                         SID_OWNER_RIGHTS,
    6893             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6894             :                                         FILE_READ_DATA,
    6895             :                                         0,
    6896             :                                         NULL);
    6897           4 :         if (newsd == NULL) {
    6898           0 :                 goto fail;
    6899             :         }
    6900           8 :         sd->dacl = security_acl_concatenate(frame,
    6901           4 :                                         newsd->dacl,
    6902           4 :                                         sd->dacl);
    6903           4 :         if (sd->dacl == NULL) {
    6904           0 :                 goto fail;
    6905             :         }
    6906           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6907           4 :         if (!NT_STATUS_IS_OK(status)) {
    6908           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6909             :                         fname, nt_errstr(status));
    6910           0 :                 goto fail;
    6911             :         }
    6912           4 :         status = cli_close(cli, fnum);
    6913           4 :         if (!NT_STATUS_IS_OK(status)) {
    6914           0 :                 printf("close failed for %s (%s)\n",
    6915             :                         fname, nt_errstr(status));
    6916           0 :                 goto fail;
    6917             :         }
    6918           4 :         fnum = (uint16_t)-1;
    6919             : 
    6920             :         /* Try and open for FILE_WRITE_DATA */
    6921           4 :         status = cli_ntcreate(cli,
    6922             :                                 fname,
    6923             :                                 0,
    6924             :                                 FILE_WRITE_DATA,
    6925             :                                 FILE_ATTRIBUTE_NORMAL,
    6926             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6927             :                                         FILE_SHARE_DELETE,
    6928             :                                 FILE_OPEN,
    6929             :                                 0,
    6930             :                                 0,
    6931             :                                 &fnum,
    6932             :                                 NULL);
    6933           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6934           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6935           0 :                 goto fail;
    6936             :         }
    6937             : 
    6938             :         /* Now try and open for FILE_READ_DATA */
    6939           4 :         status = cli_ntcreate(cli,
    6940             :                                 fname,
    6941             :                                 0,
    6942             :                                 FILE_READ_DATA,
    6943             :                                 FILE_ATTRIBUTE_NORMAL,
    6944             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6945             :                                         FILE_SHARE_DELETE,
    6946             :                                 FILE_OPEN,
    6947             :                                 0,
    6948             :                                 0,
    6949             :                                 &fnum,
    6950             :                                 NULL);
    6951           4 :         if (!NT_STATUS_IS_OK(status)) {
    6952           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6953           0 :                 goto fail;
    6954             :         }
    6955             : 
    6956           4 :         status = cli_close(cli, fnum);
    6957           4 :         if (!NT_STATUS_IS_OK(status)) {
    6958           0 :                 printf("close failed for %s (%s)\n",
    6959             :                         fname, nt_errstr(status));
    6960           0 :                 goto fail;
    6961             :         }
    6962             : 
    6963             :         /* Restore clean slate. */
    6964           4 :         TALLOC_FREE(sd);
    6965           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6966             : 
    6967             :         /* Create the test file. */
    6968           4 :         status = cli_ntcreate(cli,
    6969             :                                 fname,
    6970             :                                 0,
    6971             :                                 GENERIC_ALL_ACCESS,
    6972             :                                 FILE_ATTRIBUTE_NORMAL,
    6973             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6974             :                                         FILE_SHARE_DELETE,
    6975             :                                 FILE_CREATE,
    6976             :                                 0,
    6977             :                                 0,
    6978             :                                 &fnum,
    6979             :                                 NULL);
    6980           4 :         if (!NT_STATUS_IS_OK(status)) {
    6981           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6982           0 :                 goto fail;
    6983             :         }
    6984             : 
    6985             :         /* Get the original SD. */
    6986           4 :         status = cli_query_secdesc(cli,
    6987             :                                 fnum,
    6988             :                                 frame,
    6989             :                                 &sd);
    6990           4 :         if (!NT_STATUS_IS_OK(status)) {
    6991           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6992             :                         fname, nt_errstr(status));
    6993           0 :                 goto fail;
    6994             :         }
    6995             : 
    6996             :         /*
    6997             :          * Add an "owner-rights ACE denying WRITE_DATA,
    6998             :          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
    6999             :          */
    7000             : 
    7001           4 :         newsd = security_descriptor_dacl_create(frame,
    7002             :                                         0,
    7003             :                                         NULL,
    7004             :                                         NULL,
    7005             :                                         SID_OWNER_RIGHTS,
    7006             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7007             :                                         FILE_WRITE_DATA,
    7008             :                                         0,
    7009             :                                         SID_OWNER_RIGHTS,
    7010             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7011             :                                         FILE_READ_DATA|FILE_WRITE_DATA,
    7012             :                                         0,
    7013             :                                         NULL);
    7014           4 :         if (newsd == NULL) {
    7015           0 :                 goto fail;
    7016             :         }
    7017           8 :         sd->dacl = security_acl_concatenate(frame,
    7018           4 :                                         newsd->dacl,
    7019           4 :                                         sd->dacl);
    7020           4 :         if (sd->dacl == NULL) {
    7021           0 :                 goto fail;
    7022             :         }
    7023           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7024           4 :         if (!NT_STATUS_IS_OK(status)) {
    7025           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7026             :                         fname, nt_errstr(status));
    7027           0 :                 goto fail;
    7028             :         }
    7029           4 :         status = cli_close(cli, fnum);
    7030           4 :         if (!NT_STATUS_IS_OK(status)) {
    7031           0 :                 printf("close failed for %s (%s)\n",
    7032             :                         fname, nt_errstr(status));
    7033           0 :                 goto fail;
    7034             :         }
    7035           4 :         fnum = (uint16_t)-1;
    7036             : 
    7037             :         /* Try and open for FILE_WRITE_DATA */
    7038           4 :         status = cli_ntcreate(cli,
    7039             :                                 fname,
    7040             :                                 0,
    7041             :                                 FILE_WRITE_DATA,
    7042             :                                 FILE_ATTRIBUTE_NORMAL,
    7043             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7044             :                                         FILE_SHARE_DELETE,
    7045             :                                 FILE_OPEN,
    7046             :                                 0,
    7047             :                                 0,
    7048             :                                 &fnum,
    7049             :                                 NULL);
    7050           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    7051           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7052           0 :                 goto fail;
    7053             :         }
    7054             : 
    7055             :         /* Now try and open for FILE_READ_DATA */
    7056           4 :         status = cli_ntcreate(cli,
    7057             :                                 fname,
    7058             :                                 0,
    7059             :                                 FILE_READ_DATA,
    7060             :                                 FILE_ATTRIBUTE_NORMAL,
    7061             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7062             :                                         FILE_SHARE_DELETE,
    7063             :                                 FILE_OPEN,
    7064             :                                 0,
    7065             :                                 0,
    7066             :                                 &fnum,
    7067             :                                 NULL);
    7068           4 :         if (!NT_STATUS_IS_OK(status)) {
    7069           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7070           0 :                 goto fail;
    7071             :         }
    7072             : 
    7073           4 :         status = cli_close(cli, fnum);
    7074           4 :         if (!NT_STATUS_IS_OK(status)) {
    7075           0 :                 printf("close failed for %s (%s)\n",
    7076             :                         fname, nt_errstr(status));
    7077           0 :                 goto fail;
    7078             :         }
    7079             : 
    7080             :         /* Restore clean slate. */
    7081           4 :         TALLOC_FREE(sd);
    7082           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7083             : 
    7084             : 
    7085             :         /* Create the test file. */
    7086           4 :         status = cli_ntcreate(cli,
    7087             :                                 fname,
    7088             :                                 0,
    7089             :                                 GENERIC_ALL_ACCESS,
    7090             :                                 FILE_ATTRIBUTE_NORMAL,
    7091             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7092             :                                         FILE_SHARE_DELETE,
    7093             :                                 FILE_CREATE,
    7094             :                                 0,
    7095             :                                 0,
    7096             :                                 &fnum,
    7097             :                                 NULL);
    7098           4 :         if (!NT_STATUS_IS_OK(status)) {
    7099           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7100           0 :                 goto fail;
    7101             :         }
    7102             : 
    7103             :         /* Get the original SD. */
    7104           4 :         status = cli_query_secdesc(cli,
    7105             :                                 fnum,
    7106             :                                 frame,
    7107             :                                 &sd);
    7108           4 :         if (!NT_STATUS_IS_OK(status)) {
    7109           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    7110             :                         fname, nt_errstr(status));
    7111           0 :                 goto fail;
    7112             :         }
    7113             : 
    7114             :         /*
    7115             :          * Add an "authenticated users" ACE allowing READ_DATA,
    7116             :          * add an "owner-rights" denying READ_DATA,
    7117             :          * and an "authenticated users" ACE allowing WRITE_DATA.
    7118             :          */
    7119             : 
    7120           4 :         newsd = security_descriptor_dacl_create(frame,
    7121             :                                         0,
    7122             :                                         NULL,
    7123             :                                         NULL,
    7124             :                                         SID_NT_AUTHENTICATED_USERS,
    7125             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7126             :                                         FILE_READ_DATA,
    7127             :                                         0,
    7128             :                                         SID_OWNER_RIGHTS,
    7129             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7130             :                                         FILE_READ_DATA,
    7131             :                                         0,
    7132             :                                         SID_NT_AUTHENTICATED_USERS,
    7133             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7134             :                                         FILE_WRITE_DATA,
    7135             :                                         0,
    7136             :                                         NULL);
    7137           4 :         if (newsd == NULL) {
    7138           0 :                 printf("newsd == NULL\n");
    7139           0 :                 goto fail;
    7140             :         }
    7141           8 :         sd->dacl = security_acl_concatenate(frame,
    7142           4 :                                         newsd->dacl,
    7143           4 :                                         sd->dacl);
    7144           4 :         if (sd->dacl == NULL) {
    7145           0 :                 printf("sd->dacl == NULL\n");
    7146           0 :                 goto fail;
    7147             :         }
    7148           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7149           4 :         if (!NT_STATUS_IS_OK(status)) {
    7150           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7151             :                         fname, nt_errstr(status));
    7152           0 :                 goto fail;
    7153             :         }
    7154           4 :         status = cli_close(cli, fnum);
    7155           4 :         if (!NT_STATUS_IS_OK(status)) {
    7156           0 :                 printf("close failed for %s (%s)\n",
    7157             :                         fname, nt_errstr(status));
    7158           0 :                 goto fail;
    7159             :         }
    7160           4 :         fnum = (uint16_t)-1;
    7161             : 
    7162             :         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
    7163           4 :         status = cli_ntcreate(cli,
    7164             :                                 fname,
    7165             :                                 0,
    7166             :                                 FILE_READ_DATA|FILE_WRITE_DATA,
    7167             :                                 FILE_ATTRIBUTE_NORMAL,
    7168             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7169             :                                         FILE_SHARE_DELETE,
    7170             :                                 FILE_OPEN,
    7171             :                                 0,
    7172             :                                 0,
    7173             :                                 &fnum,
    7174             :                                 NULL);
    7175           4 :         if (!NT_STATUS_IS_OK(status)) {
    7176           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7177           0 :                 goto fail;
    7178             :         }
    7179             : 
    7180           4 :         status = cli_close(cli, fnum);
    7181           4 :         if (!NT_STATUS_IS_OK(status)) {
    7182           0 :                 printf("close failed for %s (%s)\n",
    7183             :                         fname, nt_errstr(status));
    7184           0 :                 goto fail;
    7185             :         }
    7186             : 
    7187           4 :         cli_unlink(cli, fname,
    7188             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7189             : 
    7190           4 :         TALLOC_FREE(frame);
    7191           4 :         return true;
    7192             : 
    7193           0 :   fail:
    7194             : 
    7195           0 :         if (cli) {
    7196           0 :                 if (fnum != (uint16_t)-1) {
    7197           0 :                         cli_close(cli, fnum);
    7198             :                 }
    7199           0 :                 cli_unlink(cli, fname,
    7200             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7201           0 :                 torture_close_connection(cli);
    7202             :         }
    7203             : 
    7204           0 :         TALLOC_FREE(frame);
    7205           0 :         return false;
    7206             : }
    7207             : 
    7208             : /*
    7209             :  * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
    7210             :  * Note this test only works with a user with SeSecurityPrivilege set.
    7211             :  *
    7212             :  * NB. This is also tested in samba3.base.createx_access
    7213             :  * but this makes it very explicit what we're looking for.
    7214             :  */
    7215           2 : static bool run_smb1_system_security(int dummy)
    7216             : {
    7217           0 :         static struct cli_state *cli = NULL;
    7218           2 :         const char *fname = "system_security.txt";
    7219           2 :         uint16_t fnum = (uint16_t)-1;
    7220           0 :         NTSTATUS status;
    7221           2 :         TALLOC_CTX *frame = NULL;
    7222             : 
    7223           2 :         frame = talloc_stackframe();
    7224           2 :         printf("starting smb1 system security test\n");
    7225             : 
    7226             :         /* SMB1 connection - torture_open_connection() forces this. */
    7227           2 :         if (!torture_open_connection(&cli, 0)) {
    7228           0 :                 goto fail;
    7229             :         }
    7230             : 
    7231           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    7232             : 
    7233             :         /* Start with a clean slate. */
    7234           2 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7235             : 
    7236             :         /* Create the test file. */
    7237           2 :         status = cli_ntcreate(cli,
    7238             :                                 fname,
    7239             :                                 0,
    7240             :                                 GENERIC_ALL_ACCESS,
    7241             :                                 FILE_ATTRIBUTE_NORMAL,
    7242             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7243             :                                         FILE_SHARE_DELETE,
    7244             :                                 FILE_CREATE,
    7245             :                                 0,
    7246             :                                 0,
    7247             :                                 &fnum,
    7248             :                                 NULL);
    7249           2 :         if (!NT_STATUS_IS_OK(status)) {
    7250           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7251           0 :                 goto fail;
    7252             :         }
    7253             : 
    7254           2 :         status = cli_close(cli, fnum);
    7255             : 
    7256             :         /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
    7257             :         /*
    7258             :          * On SMB1 this succeeds - SMB2 it fails,
    7259             :          * see the SMB2-SACL test.
    7260             :          */
    7261           2 :         status = cli_ntcreate(cli,
    7262             :                                 fname,
    7263             :                                 0,
    7264             :                                 SEC_FLAG_SYSTEM_SECURITY,
    7265             :                                 FILE_ATTRIBUTE_NORMAL,
    7266             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7267             :                                         FILE_SHARE_DELETE,
    7268             :                                 FILE_OPEN,
    7269             :                                 0,
    7270             :                                 0,
    7271             :                                 &fnum,
    7272             :                                 NULL);
    7273           2 :         if (!NT_STATUS_IS_OK(status)) {
    7274           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7275           0 :                 goto fail;
    7276             :         }
    7277             : 
    7278           2 :         status = cli_close(cli, fnum);
    7279             : 
    7280           2 :         cli_unlink(cli, fname,
    7281             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7282             : 
    7283           2 :         torture_close_connection(cli);
    7284           2 :         TALLOC_FREE(frame);
    7285           2 :         return true;
    7286             : 
    7287           0 :   fail:
    7288             : 
    7289           0 :         if (cli) {
    7290           0 :                 if (fnum != (uint16_t)-1) {
    7291           0 :                         cli_close(cli, fnum);
    7292             :                 }
    7293           0 :                 cli_unlink(cli, fname,
    7294             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7295           0 :                 torture_close_connection(cli);
    7296             :         }
    7297             : 
    7298           0 :         TALLOC_FREE(frame);
    7299           0 :         return false;
    7300             : }
    7301             : 
    7302           0 : static bool run_pipe_number(int dummy)
    7303             : {
    7304           0 :         struct cli_state *cli1;
    7305           0 :         const char *pipe_name = "\\SPOOLSS";
    7306           0 :         uint16_t fnum;
    7307           0 :         int num_pipes = 0;
    7308           0 :         NTSTATUS status;
    7309             : 
    7310           0 :         printf("starting pipenumber test\n");
    7311           0 :         if (!torture_open_connection(&cli1, 0)) {
    7312           0 :                 return False;
    7313             :         }
    7314             : 
    7315           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7316           0 :         while(1) {
    7317           0 :                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
    7318             :                                       FILE_ATTRIBUTE_NORMAL,
    7319             :                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
    7320             :                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
    7321           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7322           0 :                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
    7323           0 :                         break;
    7324             :                 }
    7325           0 :                 num_pipes++;
    7326           0 :                 printf("\r%6d", num_pipes);
    7327             :         }
    7328             : 
    7329           0 :         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
    7330           0 :         torture_close_connection(cli1);
    7331           0 :         return True;
    7332             : }
    7333             : 
    7334             : /*
    7335             :   Test open mode returns on read-only files.
    7336             :  */
    7337           5 : static bool run_opentest(int dummy)
    7338             : {
    7339           0 :         static struct cli_state *cli1;
    7340           0 :         static struct cli_state *cli2;
    7341           5 :         const char *fname = "\\readonly.file";
    7342           0 :         uint16_t fnum1, fnum2;
    7343           0 :         char buf[20];
    7344           0 :         off_t fsize;
    7345           5 :         bool correct = True;
    7346           0 :         char *tmp_path;
    7347           0 :         NTSTATUS status;
    7348             : 
    7349           5 :         printf("starting open test\n");
    7350             : 
    7351           5 :         if (!torture_open_connection(&cli1, 0)) {
    7352           0 :                 return False;
    7353             :         }
    7354             : 
    7355           5 :         cli_setatr(cli1, fname, 0, 0);
    7356           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7357             : 
    7358           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7359             : 
    7360           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7361           5 :         if (!NT_STATUS_IS_OK(status)) {
    7362           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7363           0 :                 return False;
    7364             :         }
    7365             : 
    7366           5 :         status = cli_close(cli1, fnum1);
    7367           5 :         if (!NT_STATUS_IS_OK(status)) {
    7368           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7369           0 :                 return False;
    7370             :         }
    7371             : 
    7372           5 :         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
    7373           5 :         if (!NT_STATUS_IS_OK(status)) {
    7374           0 :                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
    7375           0 :                 return False;
    7376             :         }
    7377             : 
    7378           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7379           5 :         if (!NT_STATUS_IS_OK(status)) {
    7380           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7381           0 :                 return False;
    7382             :         }
    7383             : 
    7384             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
    7385           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7386             : 
    7387           5 :         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
    7388           5 :                         NT_STATUS_ACCESS_DENIED)) {
    7389           4 :                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
    7390             :         }
    7391             : 
    7392           5 :         printf("finished open test 1\n");
    7393             : 
    7394           5 :         cli_close(cli1, fnum1);
    7395             : 
    7396             :         /* Now try not readonly and ensure ERRbadshare is returned. */
    7397             : 
    7398           5 :         cli_setatr(cli1, fname, 0, 0);
    7399             : 
    7400           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7401           5 :         if (!NT_STATUS_IS_OK(status)) {
    7402           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7403           0 :                 return False;
    7404             :         }
    7405             : 
    7406             :         /* This will fail - but the error should be ERRshare. */
    7407           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7408             : 
    7409           5 :         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
    7410           5 :                         NT_STATUS_SHARING_VIOLATION)) {
    7411           5 :                 printf("correct error code ERRDOS/ERRbadshare returned\n");
    7412             :         }
    7413             : 
    7414           5 :         status = cli_close(cli1, fnum1);
    7415           5 :         if (!NT_STATUS_IS_OK(status)) {
    7416           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7417           0 :                 return False;
    7418             :         }
    7419             : 
    7420           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7421             : 
    7422           5 :         printf("finished open test 2\n");
    7423             : 
    7424             :         /* Test truncate open disposition on file opened for read. */
    7425           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7426           5 :         if (!NT_STATUS_IS_OK(status)) {
    7427           0 :                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
    7428           0 :                 return False;
    7429             :         }
    7430             : 
    7431             :         /* write 20 bytes. */
    7432             : 
    7433           5 :         memset(buf, '\0', 20);
    7434             : 
    7435           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
    7436           5 :         if (!NT_STATUS_IS_OK(status)) {
    7437           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    7438           0 :                 correct = False;
    7439             :         }
    7440             : 
    7441           5 :         status = cli_close(cli1, fnum1);
    7442           5 :         if (!NT_STATUS_IS_OK(status)) {
    7443           0 :                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
    7444           0 :                 return False;
    7445             :         }
    7446             : 
    7447             :         /* Ensure size == 20. */
    7448           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7449           5 :         if (!NT_STATUS_IS_OK(status)) {
    7450           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7451           0 :                 return False;
    7452             :         }
    7453             : 
    7454           5 :         if (fsize != 20) {
    7455           0 :                 printf("(3) file size != 20\n");
    7456           0 :                 return False;
    7457             :         }
    7458             : 
    7459             :         /* Now test if we can truncate a file opened for readonly. */
    7460           5 :         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
    7461           5 :         if (!NT_STATUS_IS_OK(status)) {
    7462           0 :                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
    7463           0 :                 return False;
    7464             :         }
    7465             : 
    7466           5 :         status = cli_close(cli1, fnum1);
    7467           5 :         if (!NT_STATUS_IS_OK(status)) {
    7468           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7469           0 :                 return False;
    7470             :         }
    7471             : 
    7472             :         /* Ensure size == 0. */
    7473           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7474           5 :         if (!NT_STATUS_IS_OK(status)) {
    7475           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7476           0 :                 return False;
    7477             :         }
    7478             : 
    7479           5 :         if (fsize != 0) {
    7480           0 :                 printf("(3) file size != 0\n");
    7481           0 :                 return False;
    7482             :         }
    7483           5 :         printf("finished open test 3\n");
    7484             : 
    7485           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7486             : 
    7487           5 :         printf("Do ctemp tests\n");
    7488           5 :         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
    7489           5 :         if (!NT_STATUS_IS_OK(status)) {
    7490           0 :                 printf("ctemp failed (%s)\n", nt_errstr(status));
    7491           0 :                 return False;
    7492             :         }
    7493             : 
    7494           5 :         printf("ctemp gave path %s\n", tmp_path);
    7495           5 :         status = cli_close(cli1, fnum1);
    7496           5 :         if (!NT_STATUS_IS_OK(status)) {
    7497           0 :                 printf("close of temp failed (%s)\n", nt_errstr(status));
    7498             :         }
    7499             : 
    7500           5 :         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7501           5 :         if (!NT_STATUS_IS_OK(status)) {
    7502           0 :                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
    7503             :         }
    7504             : 
    7505             :         /* Test the non-io opens... */
    7506             : 
    7507           5 :         if (!torture_open_connection(&cli2, 1)) {
    7508           0 :                 return False;
    7509             :         }
    7510             : 
    7511           5 :         cli_setatr(cli2, fname, 0, 0);
    7512           5 :         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7513             : 
    7514           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    7515             : 
    7516           5 :         printf("TEST #1 testing 2 non-io opens (no delete)\n");
    7517           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7518             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7519             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7520           5 :         if (!NT_STATUS_IS_OK(status)) {
    7521           0 :                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7522           0 :                 return False;
    7523             :         }
    7524             : 
    7525           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7526             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7527             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7528           5 :         if (!NT_STATUS_IS_OK(status)) {
    7529           0 :                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7530           0 :                 return False;
    7531             :         }
    7532             : 
    7533           5 :         status = cli_close(cli1, fnum1);
    7534           5 :         if (!NT_STATUS_IS_OK(status)) {
    7535           0 :                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7536           0 :                 return False;
    7537             :         }
    7538             : 
    7539           5 :         status = cli_close(cli2, fnum2);
    7540           5 :         if (!NT_STATUS_IS_OK(status)) {
    7541           0 :                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7542           0 :                 return False;
    7543             :         }
    7544             : 
    7545           5 :         printf("non-io open test #1 passed.\n");
    7546             : 
    7547           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7548             : 
    7549           5 :         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
    7550             : 
    7551           5 :         status = cli_ntcreate(cli1, fname, 0,
    7552             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7553             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7554             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7555           5 :         if (!NT_STATUS_IS_OK(status)) {
    7556           0 :                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7557           0 :                 return False;
    7558             :         }
    7559             : 
    7560           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7561             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7562             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7563           5 :         if (!NT_STATUS_IS_OK(status)) {
    7564           0 :                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7565           0 :                 return False;
    7566             :         }
    7567             : 
    7568           5 :         status = cli_close(cli1, fnum1);
    7569           5 :         if (!NT_STATUS_IS_OK(status)) {
    7570           0 :                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7571           0 :                 return False;
    7572             :         }
    7573             : 
    7574           5 :         status = cli_close(cli2, fnum2);
    7575           5 :         if (!NT_STATUS_IS_OK(status)) {
    7576           0 :                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7577           0 :                 return False;
    7578             :         }
    7579             : 
    7580           5 :         printf("non-io open test #2 passed.\n");
    7581             : 
    7582           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7583             : 
    7584           5 :         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
    7585             : 
    7586           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7587             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7588             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7589           5 :         if (!NT_STATUS_IS_OK(status)) {
    7590           0 :                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7591           0 :                 return False;
    7592             :         }
    7593             : 
    7594           5 :         status = cli_ntcreate(cli2, fname, 0,
    7595             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7596             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7597             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7598           5 :         if (!NT_STATUS_IS_OK(status)) {
    7599           0 :                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7600           0 :                 return False;
    7601             :         }
    7602             : 
    7603           5 :         status = cli_close(cli1, fnum1);
    7604           5 :         if (!NT_STATUS_IS_OK(status)) {
    7605           0 :                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7606           0 :                 return False;
    7607             :         }
    7608             : 
    7609           5 :         status = cli_close(cli2, fnum2);
    7610           5 :         if (!NT_STATUS_IS_OK(status)) {
    7611           0 :                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7612           0 :                 return False;
    7613             :         }
    7614             : 
    7615           5 :         printf("non-io open test #3 passed.\n");
    7616             : 
    7617           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7618             : 
    7619           5 :         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
    7620             : 
    7621           5 :         status = cli_ntcreate(cli1, fname, 0,
    7622             :                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7623             :                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7624             :                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7625           5 :         if (!NT_STATUS_IS_OK(status)) {
    7626           0 :                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7627           0 :                 return False;
    7628             :         }
    7629             : 
    7630           5 :         status = cli_ntcreate(cli2, fname, 0,
    7631             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7632             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7633             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7634           5 :         if (NT_STATUS_IS_OK(status)) {
    7635           0 :                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7636           0 :                 return False;
    7637             :         }
    7638             : 
    7639           5 :         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7640             : 
    7641           5 :         status = cli_close(cli1, fnum1);
    7642           5 :         if (!NT_STATUS_IS_OK(status)) {
    7643           0 :                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7644           0 :                 return False;
    7645             :         }
    7646             : 
    7647           5 :         printf("non-io open test #4 passed.\n");
    7648             : 
    7649           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7650             : 
    7651           5 :         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    7652             : 
    7653           5 :         status = cli_ntcreate(cli1, fname, 0,
    7654             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7655             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7656             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7657           5 :         if (!NT_STATUS_IS_OK(status)) {
    7658           0 :                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7659           0 :                 return False;
    7660             :         }
    7661             : 
    7662           5 :         status = cli_ntcreate(cli2, fname, 0,
    7663             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7664             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7665             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7666           5 :         if (!NT_STATUS_IS_OK(status)) {
    7667           0 :                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7668           0 :                 return False;
    7669             :         }
    7670             : 
    7671           5 :         status = cli_close(cli1, fnum1);
    7672           5 :         if (!NT_STATUS_IS_OK(status)) {
    7673           0 :                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7674           0 :                 return False;
    7675             :         }
    7676             : 
    7677           5 :         status = cli_close(cli2, fnum2);
    7678           5 :         if (!NT_STATUS_IS_OK(status)) {
    7679           0 :                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7680           0 :                 return False;
    7681             :         }
    7682             : 
    7683           5 :         printf("non-io open test #5 passed.\n");
    7684             : 
    7685           5 :         printf("TEST #6 testing 1 non-io open, one io open\n");
    7686             : 
    7687           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7688             : 
    7689           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7690             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7691             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7692           5 :         if (!NT_STATUS_IS_OK(status)) {
    7693           0 :                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7694           0 :                 return False;
    7695             :         }
    7696             : 
    7697           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7698             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    7699             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7700           5 :         if (!NT_STATUS_IS_OK(status)) {
    7701           0 :                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7702           0 :                 return False;
    7703             :         }
    7704             : 
    7705           5 :         status = cli_close(cli1, fnum1);
    7706           5 :         if (!NT_STATUS_IS_OK(status)) {
    7707           0 :                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7708           0 :                 return False;
    7709             :         }
    7710             : 
    7711           5 :         status = cli_close(cli2, fnum2);
    7712           5 :         if (!NT_STATUS_IS_OK(status)) {
    7713           0 :                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7714           0 :                 return False;
    7715             :         }
    7716             : 
    7717           5 :         printf("non-io open test #6 passed.\n");
    7718             : 
    7719           5 :         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
    7720             : 
    7721           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7722             : 
    7723           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7724             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7725             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7726           5 :         if (!NT_STATUS_IS_OK(status)) {
    7727           0 :                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7728           0 :                 return False;
    7729             :         }
    7730             : 
    7731           5 :         status = cli_ntcreate(cli2, fname, 0,
    7732             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7733             :                               FILE_ATTRIBUTE_NORMAL,
    7734             :                               FILE_SHARE_READ|FILE_SHARE_DELETE,
    7735             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7736           5 :         if (NT_STATUS_IS_OK(status)) {
    7737           0 :                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7738           0 :                 return False;
    7739             :         }
    7740             : 
    7741           5 :         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7742             : 
    7743           5 :         status = cli_close(cli1, fnum1);
    7744           5 :         if (!NT_STATUS_IS_OK(status)) {
    7745           0 :                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7746           0 :                 return False;
    7747             :         }
    7748             : 
    7749           5 :         printf("non-io open test #7 passed.\n");
    7750             : 
    7751           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7752             : 
    7753           5 :         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
    7754           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
    7755             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7756             :                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7757           5 :         if (!NT_STATUS_IS_OK(status)) {
    7758           0 :                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
    7759           0 :                 correct = false;
    7760           0 :                 goto out;
    7761             :         }
    7762             : 
    7763             :         /* Write to ensure we have to update the file time. */
    7764           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7765             :                               NULL);
    7766           5 :         if (!NT_STATUS_IS_OK(status)) {
    7767           0 :                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
    7768           0 :                 correct = false;
    7769           0 :                 goto out;
    7770             :         }
    7771             : 
    7772           5 :         status = cli_close(cli1, fnum1);
    7773           5 :         if (!NT_STATUS_IS_OK(status)) {
    7774           0 :                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
    7775           0 :                 correct = false;
    7776             :         }
    7777             : 
    7778           5 :   out:
    7779             : 
    7780           5 :         if (!torture_close_connection(cli1)) {
    7781           0 :                 correct = False;
    7782             :         }
    7783           5 :         if (!torture_close_connection(cli2)) {
    7784           0 :                 correct = False;
    7785             :         }
    7786             : 
    7787           5 :         return correct;
    7788             : }
    7789             : 
    7790         102 : NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
    7791             : {
    7792           0 :         uint16_t major, minor;
    7793           0 :         uint32_t caplow, caphigh;
    7794           0 :         NTSTATUS status;
    7795             : 
    7796         102 :         if (!SERVER_HAS_UNIX_CIFS(cli)) {
    7797           0 :                 printf("Server doesn't support UNIX CIFS extensions.\n");
    7798           0 :                 return NT_STATUS_NOT_SUPPORTED;
    7799             :         }
    7800             : 
    7801         102 :         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
    7802             :                                              &caphigh);
    7803         102 :         if (!NT_STATUS_IS_OK(status)) {
    7804           0 :                 printf("Server didn't return UNIX CIFS extensions: %s\n",
    7805             :                        nt_errstr(status));
    7806           0 :                 return status;
    7807             :         }
    7808             : 
    7809         102 :         status = cli_set_unix_extensions_capabilities(cli, major, minor,
    7810             :                                                       caplow, caphigh);
    7811         102 :         if (!NT_STATUS_IS_OK(status)) {
    7812           0 :                 printf("Server doesn't support setting UNIX CIFS extensions: "
    7813             :                        "%s.\n", nt_errstr(status));
    7814           0 :                 return status;
    7815             :         }
    7816             : 
    7817         102 :         return NT_STATUS_OK;
    7818             : }
    7819             : 
    7820             : /*
    7821             :   Test POSIX open /mkdir calls.
    7822             :  */
    7823           4 : static bool run_simple_posix_open_test(int dummy)
    7824             : {
    7825           0 :         static struct cli_state *cli1;
    7826           4 :         const char *fname = "posix:file";
    7827           4 :         const char *hname = "posix:hlink";
    7828           4 :         const char *sname = "posix:symlink";
    7829           4 :         const char *dname = "posix:dir";
    7830           0 :         char buf[10];
    7831           4 :         char *target = NULL;
    7832           4 :         uint16_t fnum1 = (uint16_t)-1;
    7833           0 :         SMB_STRUCT_STAT sbuf;
    7834           4 :         bool correct = false;
    7835           0 :         NTSTATUS status;
    7836           0 :         size_t nread;
    7837           4 :         const char *fname_windows = "windows_file";
    7838           4 :         uint16_t fnum2 = (uint16_t)-1;
    7839           0 :         bool ok;
    7840             : 
    7841           4 :         printf("Starting simple POSIX open test\n");
    7842             : 
    7843           4 :         if (!torture_open_connection(&cli1, 0)) {
    7844           0 :                 return false;
    7845             :         }
    7846             : 
    7847           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7848             : 
    7849           4 :         status = torture_setup_unix_extensions(cli1);
    7850           4 :         if (!NT_STATUS_IS_OK(status)) {
    7851           0 :                 return false;
    7852             :         }
    7853             : 
    7854           4 :         cli_setatr(cli1, fname, 0, 0);
    7855           4 :         cli_posix_unlink(cli1, fname);
    7856           4 :         cli_setatr(cli1, dname, 0, 0);
    7857           4 :         cli_posix_rmdir(cli1, dname);
    7858           4 :         cli_setatr(cli1, hname, 0, 0);
    7859           4 :         cli_posix_unlink(cli1, hname);
    7860           4 :         cli_setatr(cli1, sname, 0, 0);
    7861           4 :         cli_posix_unlink(cli1, sname);
    7862           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    7863           4 :         cli_posix_unlink(cli1, fname_windows);
    7864             : 
    7865             :         /* Create a directory. */
    7866           4 :         status = cli_posix_mkdir(cli1, dname, 0777);
    7867           4 :         if (!NT_STATUS_IS_OK(status)) {
    7868           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7869           0 :                 goto out;
    7870             :         }
    7871             : 
    7872           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7873             :                                 0600, &fnum1);
    7874           4 :         if (!NT_STATUS_IS_OK(status)) {
    7875           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7876           0 :                 goto out;
    7877             :         }
    7878             : 
    7879             :         /* Test ftruncate - set file size. */
    7880           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7881           4 :         if (!NT_STATUS_IS_OK(status)) {
    7882           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7883           0 :                 goto out;
    7884             :         }
    7885             : 
    7886             :         /* Ensure st_size == 1000 */
    7887           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7888           4 :         if (!NT_STATUS_IS_OK(status)) {
    7889           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7890           0 :                 goto out;
    7891             :         }
    7892             : 
    7893           4 :         if (sbuf.st_ex_size != 1000) {
    7894           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7895           0 :                 goto out;
    7896             :         }
    7897             : 
    7898             :         /* Ensure st_mode == 0600 */
    7899           4 :         if ((sbuf.st_ex_mode & 07777) != 0600) {
    7900           0 :                 printf("posix_open - bad permissions 0%o != 0600\n",
    7901           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7902           0 :                 goto out;
    7903             :         }
    7904             : 
    7905             :         /* Test ftruncate - set file size back to zero. */
    7906           4 :         status = cli_ftruncate(cli1, fnum1, 0);
    7907           4 :         if (!NT_STATUS_IS_OK(status)) {
    7908           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7909           0 :                 goto out;
    7910             :         }
    7911             : 
    7912           4 :         status = cli_close(cli1, fnum1);
    7913           4 :         if (!NT_STATUS_IS_OK(status)) {
    7914           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7915           0 :                 goto out;
    7916             :         }
    7917             : 
    7918             :         /* Now open the file again for read only. */
    7919           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7920           4 :         if (!NT_STATUS_IS_OK(status)) {
    7921           0 :                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
    7922           0 :                 goto out;
    7923             :         }
    7924             : 
    7925             :         /* Now unlink while open. */
    7926           4 :         status = cli_posix_unlink(cli1, fname);
    7927           4 :         if (!NT_STATUS_IS_OK(status)) {
    7928           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7929           0 :                 goto out;
    7930             :         }
    7931             : 
    7932           4 :         status = cli_close(cli1, fnum1);
    7933           4 :         if (!NT_STATUS_IS_OK(status)) {
    7934           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7935           0 :                 goto out;
    7936             :         }
    7937             : 
    7938             :         /* Ensure the file has gone. */
    7939           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7940           4 :         if (NT_STATUS_IS_OK(status)) {
    7941           0 :                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
    7942           0 :                 goto out;
    7943             :         }
    7944             : 
    7945             :         /* Create again to test open with O_TRUNC. */
    7946           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
    7947           4 :         if (!NT_STATUS_IS_OK(status)) {
    7948           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7949           0 :                 goto out;
    7950             :         }
    7951             : 
    7952             :         /* Test ftruncate - set file size. */
    7953           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7954           4 :         if (!NT_STATUS_IS_OK(status)) {
    7955           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7956           0 :                 goto out;
    7957             :         }
    7958             : 
    7959             :         /* Ensure st_size == 1000 */
    7960           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7961           4 :         if (!NT_STATUS_IS_OK(status)) {
    7962           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7963           0 :                 goto out;
    7964             :         }
    7965             : 
    7966           4 :         if (sbuf.st_ex_size != 1000) {
    7967           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7968           0 :                 goto out;
    7969             :         }
    7970             : 
    7971           4 :         status = cli_close(cli1, fnum1);
    7972           4 :         if (!NT_STATUS_IS_OK(status)) {
    7973           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7974           0 :                 goto out;
    7975             :         }
    7976             : 
    7977             :         /* Re-open with O_TRUNC. */
    7978           4 :         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
    7979           4 :         if (!NT_STATUS_IS_OK(status)) {
    7980           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7981           0 :                 goto out;
    7982             :         }
    7983             : 
    7984             :         /* Ensure st_size == 0 */
    7985           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7986           4 :         if (!NT_STATUS_IS_OK(status)) {
    7987           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7988           0 :                 goto out;
    7989             :         }
    7990             : 
    7991           4 :         if (sbuf.st_ex_size != 0) {
    7992           0 :                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
    7993           0 :                 goto out;
    7994             :         }
    7995             : 
    7996           4 :         status = cli_close(cli1, fnum1);
    7997           4 :         if (!NT_STATUS_IS_OK(status)) {
    7998           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7999           0 :                 goto out;
    8000             :         }
    8001             : 
    8002           4 :         status = cli_posix_unlink(cli1, fname);
    8003           4 :         if (!NT_STATUS_IS_OK(status)) {
    8004           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    8005           0 :                 goto out;
    8006             :         }
    8007             : 
    8008           4 :         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
    8009           4 :         if (!NT_STATUS_IS_OK(status)) {
    8010           0 :                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
    8011             :                         dname, nt_errstr(status));
    8012           0 :                 goto out;
    8013             :         }
    8014             : 
    8015           4 :         cli_close(cli1, fnum1);
    8016             : 
    8017             :         /* What happens when we try and POSIX open a directory for write ? */
    8018           4 :         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
    8019           4 :         if (NT_STATUS_IS_OK(status)) {
    8020           0 :                 printf("POSIX open of directory %s succeeded, "
    8021             :                        "should have failed.\n",
    8022             :                        dname);
    8023           0 :                 goto out;
    8024             :         } else {
    8025           4 :                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
    8026           4 :                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
    8027           0 :                         goto out;
    8028             :                 }
    8029             :         }
    8030             : 
    8031             :         /* Create the file. */
    8032           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    8033             :                                 0600, &fnum1);
    8034           4 :         if (!NT_STATUS_IS_OK(status)) {
    8035           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    8036           0 :                 goto out;
    8037             :         }
    8038             : 
    8039             :         /* Write some data into it. */
    8040           4 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    8041             :                               NULL);
    8042           4 :         if (!NT_STATUS_IS_OK(status)) {
    8043           0 :                 printf("cli_write failed: %s\n", nt_errstr(status));
    8044           0 :                 goto out;
    8045             :         }
    8046             : 
    8047           4 :         cli_close(cli1, fnum1);
    8048             : 
    8049             :         /* Now create a hardlink. */
    8050           4 :         status = cli_posix_hardlink(cli1, fname, hname);
    8051           4 :         if (!NT_STATUS_IS_OK(status)) {
    8052           0 :                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
    8053           0 :                 goto out;
    8054             :         }
    8055             : 
    8056             :         /* Now create a symlink. */
    8057           4 :         status = cli_posix_symlink(cli1, fname, sname);
    8058           4 :         if (!NT_STATUS_IS_OK(status)) {
    8059           0 :                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
    8060           0 :                 goto out;
    8061             :         }
    8062             : 
    8063             :         /* Open the hardlink for read. */
    8064           4 :         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
    8065           4 :         if (!NT_STATUS_IS_OK(status)) {
    8066           0 :                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
    8067           0 :                 goto out;
    8068             :         }
    8069             : 
    8070           4 :         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
    8071           4 :         if (!NT_STATUS_IS_OK(status)) {
    8072           0 :                 printf("POSIX read of %s failed (%s)\n", hname,
    8073             :                        nt_errstr(status));
    8074           0 :                 goto out;
    8075           4 :         } else if (nread != 10) {
    8076           0 :                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
    8077             :                        hname, (unsigned long)nread, 10);
    8078           0 :                 goto out;
    8079             :         }
    8080             : 
    8081           4 :         if (memcmp(buf, "TEST DATA\n", 10)) {
    8082           0 :                 printf("invalid data read from hardlink\n");
    8083           0 :                 goto out;
    8084             :         }
    8085             : 
    8086             :         /* Do a POSIX lock/unlock. */
    8087           4 :         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
    8088           4 :         if (!NT_STATUS_IS_OK(status)) {
    8089           0 :                 printf("POSIX lock failed %s\n", nt_errstr(status));
    8090           0 :                 goto out;
    8091             :         }
    8092             : 
    8093             :         /* Punch a hole in the locked area. */
    8094           4 :         status = cli_posix_unlock(cli1, fnum1, 10, 80);
    8095           4 :         if (!NT_STATUS_IS_OK(status)) {
    8096           0 :                 printf("POSIX unlock failed %s\n", nt_errstr(status));
    8097           0 :                 goto out;
    8098             :         }
    8099             : 
    8100           4 :         cli_close(cli1, fnum1);
    8101             : 
    8102             :         /* Open the symlink for read - this should fail. A POSIX
    8103             :            client should not be doing opens on a symlink. */
    8104           4 :         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
    8105           4 :         if (NT_STATUS_IS_OK(status)) {
    8106           0 :                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
    8107           0 :                 goto out;
    8108             :         }
    8109           4 :         ok = check_both_error(
    8110             :                 __LINE__, status, ERRDOS, ERRbadpath,
    8111           4 :                 NT_STATUS_OBJECT_NAME_NOT_FOUND);
    8112           4 :         if (!ok) {
    8113           0 :                 printf("POSIX open of %s should have failed "
    8114             :                        "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
    8115             :                        "failed with %s instead.\n",
    8116             :                        sname, nt_errstr(status));
    8117           0 :                 goto out;
    8118             :         }
    8119             : 
    8120           4 :         status = cli_readlink(cli1, sname, talloc_tos(), &target, NULL, NULL);
    8121           4 :         if (!NT_STATUS_IS_OK(status)) {
    8122           0 :                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
    8123           0 :                 goto out;
    8124             :         }
    8125             : 
    8126           4 :         if (strcmp(target, fname) != 0) {
    8127           0 :                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
    8128             :                         sname, fname, target);
    8129           0 :                 goto out;
    8130             :         }
    8131             : 
    8132           4 :         status = cli_posix_rmdir(cli1, dname);
    8133           4 :         if (!NT_STATUS_IS_OK(status)) {
    8134           0 :                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
    8135           0 :                 goto out;
    8136             :         }
    8137             : 
    8138             :         /* Check directory opens with a specific permission. */
    8139           4 :         status = cli_posix_mkdir(cli1, dname, 0700);
    8140           4 :         if (!NT_STATUS_IS_OK(status)) {
    8141           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    8142           0 :                 goto out;
    8143             :         }
    8144             : 
    8145             :         /* Ensure st_mode == 0700 */
    8146           4 :         status = cli_posix_stat(cli1, dname, &sbuf);
    8147           4 :         if (!NT_STATUS_IS_OK(status)) {
    8148           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    8149           0 :                 goto out;
    8150             :         }
    8151             : 
    8152           4 :         if ((sbuf.st_ex_mode & 07777) != 0700) {
    8153           0 :                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
    8154           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    8155           0 :                 goto out;
    8156             :         }
    8157             : 
    8158             :         /*
    8159             :          * Now create a Windows file, and attempt a POSIX unlink.
    8160             :          * This should fail with a sharing violation but due to:
    8161             :          *
    8162             :          * [Bug 9571] Unlink after open causes smbd to panic
    8163             :          *
    8164             :          * ensure we've fixed the lock ordering violation.
    8165             :          */
    8166             : 
    8167           4 :         status = cli_ntcreate(cli1, fname_windows, 0,
    8168             :                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
    8169             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8170             :                         FILE_CREATE,
    8171             :                         0x0, 0x0, &fnum2, NULL);
    8172           4 :         if (!NT_STATUS_IS_OK(status)) {
    8173           0 :                 printf("Windows create of %s failed (%s)\n", fname_windows,
    8174             :                         nt_errstr(status));
    8175           0 :                 goto out;
    8176             :         }
    8177             : 
    8178             :         /* Now try posix_unlink. */
    8179           4 :         status = cli_posix_unlink(cli1, fname_windows);
    8180           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8181           0 :                 printf("POSIX unlink of %s should fail "
    8182             :                         "with NT_STATUS_SHARING_VIOLATION "
    8183             :                         "got %s instead !\n",
    8184             :                         fname_windows,
    8185             :                         nt_errstr(status));
    8186           0 :                 goto out;
    8187             :         }
    8188             : 
    8189           4 :         cli_close(cli1, fnum2);
    8190             : 
    8191           4 :         printf("Simple POSIX open test passed\n");
    8192           4 :         correct = true;
    8193             : 
    8194           4 :   out:
    8195             : 
    8196           4 :         if (fnum1 != (uint16_t)-1) {
    8197           4 :                 cli_close(cli1, fnum1);
    8198           4 :                 fnum1 = (uint16_t)-1;
    8199             :         }
    8200             : 
    8201           4 :         if (fnum2 != (uint16_t)-1) {
    8202           4 :                 cli_close(cli1, fnum2);
    8203           4 :                 fnum2 = (uint16_t)-1;
    8204             :         }
    8205             : 
    8206           4 :         cli_setatr(cli1, sname, 0, 0);
    8207           4 :         cli_posix_unlink(cli1, sname);
    8208           4 :         cli_setatr(cli1, hname, 0, 0);
    8209           4 :         cli_posix_unlink(cli1, hname);
    8210           4 :         cli_setatr(cli1, fname, 0, 0);
    8211           4 :         cli_posix_unlink(cli1, fname);
    8212           4 :         cli_setatr(cli1, dname, 0, 0);
    8213           4 :         cli_posix_rmdir(cli1, dname);
    8214           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    8215           4 :         cli_posix_unlink(cli1, fname_windows);
    8216             : 
    8217           4 :         if (!torture_close_connection(cli1)) {
    8218           0 :                 correct = false;
    8219             :         }
    8220             : 
    8221           4 :         return correct;
    8222             : }
    8223             : 
    8224             : /*
    8225             :   Test POSIX and Windows ACLs are rejected on symlinks.
    8226             :  */
    8227           4 : static bool run_acl_symlink_test(int dummy)
    8228             : {
    8229           0 :         static struct cli_state *cli;
    8230           4 :         const char *fname = "posix_file";
    8231           4 :         const char *sname = "posix_symlink";
    8232           4 :         uint16_t fnum = (uint16_t)-1;
    8233           4 :         bool correct = false;
    8234           0 :         NTSTATUS status;
    8235           4 :         char *posix_acl = NULL;
    8236           4 :         size_t posix_acl_len = 0;
    8237           4 :         char *posix_acl_sym = NULL;
    8238           4 :         size_t posix_acl_len_sym = 0;
    8239           4 :         struct security_descriptor *sd = NULL;
    8240           4 :         TALLOC_CTX *frame = NULL;
    8241             : 
    8242           4 :         frame = talloc_stackframe();
    8243             : 
    8244           4 :         printf("Starting acl symlink test\n");
    8245             : 
    8246           4 :         if (!torture_open_connection(&cli, 0)) {
    8247           0 :                 TALLOC_FREE(frame);
    8248           0 :                 return false;
    8249             :         }
    8250             : 
    8251           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8252             : 
    8253           4 :         status = torture_setup_unix_extensions(cli);
    8254           4 :         if (!NT_STATUS_IS_OK(status)) {
    8255           0 :                 TALLOC_FREE(frame);
    8256           0 :                 return false;
    8257             :         }
    8258             : 
    8259           4 :         cli_setatr(cli, fname, 0, 0);
    8260           4 :         cli_posix_unlink(cli, fname);
    8261           4 :         cli_setatr(cli, sname, 0, 0);
    8262           4 :         cli_posix_unlink(cli, sname);
    8263             : 
    8264           4 :         status = cli_ntcreate(cli,
    8265             :                         fname,
    8266             :                         0,
    8267             :                         READ_CONTROL_ACCESS,
    8268             :                         0,
    8269             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8270             :                         FILE_CREATE,
    8271             :                         0x0,
    8272             :                         0x0,
    8273             :                         &fnum,
    8274             :                         NULL);
    8275             : 
    8276           4 :         if (!NT_STATUS_IS_OK(status)) {
    8277           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8278             :                         fname,
    8279             :                         nt_errstr(status));
    8280           0 :                 goto out;
    8281             :         }
    8282             : 
    8283             :         /* Get the Windows ACL on the file. */
    8284           4 :         status = cli_query_secdesc(cli,
    8285             :                                 fnum,
    8286             :                                 frame,
    8287             :                                 &sd);
    8288           4 :         if (!NT_STATUS_IS_OK(status)) {
    8289           0 :                 printf("cli_query_secdesc failed (%s)\n",
    8290             :                         nt_errstr(status));
    8291           0 :                 goto out;
    8292             :         }
    8293             : 
    8294             :         /* Get the POSIX ACL on the file. */
    8295           4 :         status = cli_posix_getacl(cli,
    8296             :                                 fname,
    8297             :                                 frame,
    8298             :                                 &posix_acl_len,
    8299             :                                 &posix_acl);
    8300             : 
    8301           4 :         if (!NT_STATUS_IS_OK(status)) {
    8302           0 :                 printf("cli_posix_getacl failed (%s)\n",
    8303             :                         nt_errstr(status));
    8304           0 :                 goto out;
    8305             :         }
    8306             : 
    8307           4 :         status = cli_close(cli, fnum);
    8308           4 :         if (!NT_STATUS_IS_OK(status)) {
    8309           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8310           0 :                 goto out;
    8311             :         }
    8312           4 :         fnum = (uint16_t)-1;
    8313             : 
    8314             :         /* Now create a symlink. */
    8315           4 :         status = cli_posix_symlink(cli, fname, sname);
    8316           4 :         if (!NT_STATUS_IS_OK(status)) {
    8317           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8318             :                         sname,
    8319             :                         fname,
    8320             :                         nt_errstr(status));
    8321           0 :                 goto out;
    8322             :         }
    8323             : 
    8324             :         /* Open a handle on the symlink for SD set/get should fail. */
    8325           4 :         status = cli_ntcreate(cli,
    8326             :                         sname,
    8327             :                         0,
    8328             :                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
    8329             :                         0,
    8330             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8331             :                         FILE_OPEN,
    8332             :                         0x0,
    8333             :                         0x0,
    8334             :                         &fnum,
    8335             :                         NULL);
    8336             : 
    8337           4 :         if (NT_STATUS_IS_OK(status)) {
    8338           0 :                 printf("Symlink open for getsd/setsd of %s "
    8339             :                         "succeeded (should fail)\n",
    8340             :                         sname);
    8341           0 :                 goto out;
    8342             :         }
    8343             : 
    8344             :         /* Try a stat-open on the symlink, should also fail. */
    8345           4 :         status = cli_ntcreate(cli,
    8346             :                         sname,
    8347             :                         0,
    8348             :                         FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
    8349             :                         0,
    8350             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8351             :                         FILE_OPEN,
    8352             :                         0x0,
    8353             :                         0x0,
    8354             :                         &fnum,
    8355             :                         NULL);
    8356             : 
    8357           4 :         if (NT_STATUS_IS_OK(status)) {
    8358           0 :                 printf("Stat-open of symlink succeeded (should fail)\n");
    8359           0 :                 goto out;
    8360             :         }
    8361             : 
    8362             :         /* Get the POSIX ACL on the symlink pathname. Should fail. */
    8363           4 :         status = cli_posix_getacl(cli,
    8364             :                                 sname,
    8365             :                                 frame,
    8366             :                                 &posix_acl_len_sym,
    8367             :                                 &posix_acl_sym);
    8368             : 
    8369           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8370           0 :                 printf("cli_posix_getacl on a symlink gave %s. "
    8371             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8372             :                         nt_errstr(status));
    8373           0 :                 goto out;
    8374             :         }
    8375             : 
    8376             :         /* Set the POSIX ACL on the symlink pathname. Should fail. */
    8377           4 :         status = cli_posix_setacl(cli,
    8378             :                                 sname,
    8379             :                                 posix_acl,
    8380             :                                 posix_acl_len);
    8381             : 
    8382           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8383           0 :                 printf("cli_posix_setacl on a symlink gave %s. "
    8384             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8385             :                         nt_errstr(status));
    8386           0 :                 goto out;
    8387             :         }
    8388             : 
    8389           4 :         printf("ACL symlink test passed\n");
    8390           4 :         correct = true;
    8391             : 
    8392           4 :   out:
    8393             : 
    8394           4 :         if (fnum != (uint16_t)-1) {
    8395           0 :                 cli_close(cli, fnum);
    8396           0 :                 fnum = (uint16_t)-1;
    8397             :         }
    8398             : 
    8399           4 :         cli_setatr(cli, sname, 0, 0);
    8400           4 :         cli_posix_unlink(cli, sname);
    8401           4 :         cli_setatr(cli, fname, 0, 0);
    8402           4 :         cli_posix_unlink(cli, fname);
    8403             : 
    8404           4 :         if (!torture_close_connection(cli)) {
    8405           0 :                 correct = false;
    8406             :         }
    8407             : 
    8408           4 :         TALLOC_FREE(frame);
    8409           4 :         return correct;
    8410             : }
    8411             : 
    8412             : /*
    8413             :   Test POSIX can delete a file containing streams.
    8414             :  */
    8415           4 : static bool run_posix_stream_delete(int dummy)
    8416             : {
    8417           4 :         struct cli_state *cli1 = NULL;
    8418           4 :         struct cli_state *cli2 = NULL;
    8419           4 :         const char *fname = "streamfile";
    8420           4 :         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
    8421           4 :         uint16_t fnum1 = (uint16_t)-1;
    8422           4 :         bool correct = false;
    8423           0 :         NTSTATUS status;
    8424           4 :         TALLOC_CTX *frame = NULL;
    8425             : 
    8426           4 :         frame = talloc_stackframe();
    8427             : 
    8428           4 :         printf("Starting POSIX stream delete test\n");
    8429             : 
    8430           4 :         if (!torture_open_connection(&cli1, 0) ||
    8431           4 :                         !torture_open_connection(&cli2, 1)) {
    8432           0 :                 TALLOC_FREE(frame);
    8433           0 :                 return false;
    8434             :         }
    8435             : 
    8436           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8437           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    8438             : 
    8439           4 :         status = torture_setup_unix_extensions(cli2);
    8440           4 :         if (!NT_STATUS_IS_OK(status)) {
    8441           0 :                 goto out;
    8442             :         }
    8443             : 
    8444           4 :         cli_setatr(cli1, fname, 0, 0);
    8445           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8446             : 
    8447             :         /* Create the file. */
    8448           4 :         status = cli_ntcreate(cli1,
    8449             :                         fname,
    8450             :                         0,
    8451             :                         READ_CONTROL_ACCESS,
    8452             :                         0,
    8453             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8454             :                         FILE_CREATE,
    8455             :                         0x0,
    8456             :                         0x0,
    8457             :                         &fnum1,
    8458             :                         NULL);
    8459             : 
    8460           4 :         if (!NT_STATUS_IS_OK(status)) {
    8461           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8462             :                         fname,
    8463             :                         nt_errstr(status));
    8464           0 :                 goto out;
    8465             :         }
    8466             : 
    8467           4 :         status = cli_close(cli1, fnum1);
    8468           4 :         if (!NT_STATUS_IS_OK(status)) {
    8469           0 :                 printf("cli_close of %s failed (%s)\n",
    8470             :                         fname,
    8471             :                         nt_errstr(status));
    8472           0 :                 goto out;
    8473             :         }
    8474           4 :         fnum1 = (uint16_t)-1;
    8475             : 
    8476             :         /* Now create the stream. */
    8477           4 :         status = cli_ntcreate(cli1,
    8478             :                         stream_fname,
    8479             :                         0,
    8480             :                         FILE_WRITE_DATA,
    8481             :                         0,
    8482             :                         FILE_SHARE_READ|FILE_SHARE_WRITE,
    8483             :                         FILE_CREATE,
    8484             :                         0x0,
    8485             :                         0x0,
    8486             :                         &fnum1,
    8487             :                         NULL);
    8488             : 
    8489           4 :         if (!NT_STATUS_IS_OK(status)) {
    8490           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8491             :                         stream_fname,
    8492             :                         nt_errstr(status));
    8493           0 :                 goto out;
    8494             :         }
    8495             : 
    8496             :         /* Leave the stream handle open... */
    8497             : 
    8498             :         /* POSIX unlink should fail. */
    8499           4 :         status = cli_posix_unlink(cli2, fname);
    8500           4 :         if (NT_STATUS_IS_OK(status)) {
    8501           0 :                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
    8502             :                         fname);
    8503           0 :                 goto out;
    8504             :         }
    8505             : 
    8506           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8507           0 :                 printf("cli_posix_unlink of %s failed with (%s) "
    8508             :                         "should have been NT_STATUS_SHARING_VIOLATION\n",
    8509             :                         fname,
    8510             :                         nt_errstr(status));
    8511           0 :                 goto out;
    8512             :         }
    8513             : 
    8514             :         /* Close the stream handle. */
    8515           4 :         status = cli_close(cli1, fnum1);
    8516           4 :         if (!NT_STATUS_IS_OK(status)) {
    8517           0 :                 printf("cli_close of %s failed (%s)\n",
    8518             :                         stream_fname,
    8519             :                         nt_errstr(status));
    8520           0 :                 goto out;
    8521             :         }
    8522           4 :         fnum1 = (uint16_t)-1;
    8523             : 
    8524             :         /* POSIX unlink after stream handle closed should succeed. */
    8525           4 :         status = cli_posix_unlink(cli2, fname);
    8526           4 :         if (!NT_STATUS_IS_OK(status)) {
    8527           0 :                 printf("cli_posix_unlink of %s failed (%s)\n",
    8528             :                         fname,
    8529             :                         nt_errstr(status));
    8530           0 :                 goto out;
    8531             :         }
    8532             : 
    8533           4 :         printf("POSIX stream delete test passed\n");
    8534           4 :         correct = true;
    8535             : 
    8536           4 :   out:
    8537             : 
    8538           4 :         if (fnum1 != (uint16_t)-1) {
    8539           0 :                 cli_close(cli1, fnum1);
    8540           0 :                 fnum1 = (uint16_t)-1;
    8541             :         }
    8542             : 
    8543           4 :         cli_setatr(cli1, fname, 0, 0);
    8544           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8545             : 
    8546           4 :         if (!torture_close_connection(cli1)) {
    8547           0 :                 correct = false;
    8548             :         }
    8549           4 :         if (!torture_close_connection(cli2)) {
    8550           0 :                 correct = false;
    8551             :         }
    8552             : 
    8553           4 :         TALLOC_FREE(frame);
    8554           4 :         return correct;
    8555             : }
    8556             : 
    8557             : /*
    8558             :   Test setting EA's are rejected on symlinks.
    8559             :  */
    8560           4 : static bool run_ea_symlink_test(int dummy)
    8561             : {
    8562           0 :         static struct cli_state *cli;
    8563           4 :         const char *fname = "posix_file_ea";
    8564           4 :         const char *sname = "posix_symlink_ea";
    8565           4 :         const char *ea_name = "testea_name";
    8566           4 :         const char *ea_value = "testea_value";
    8567           4 :         uint16_t fnum = (uint16_t)-1;
    8568           4 :         bool correct = false;
    8569           0 :         NTSTATUS status;
    8570           0 :         size_t i, num_eas;
    8571           4 :         struct ea_struct *eas = NULL;
    8572           4 :         TALLOC_CTX *frame = NULL;
    8573             : 
    8574           4 :         frame = talloc_stackframe();
    8575             : 
    8576           4 :         printf("Starting EA symlink test\n");
    8577             : 
    8578           4 :         if (!torture_open_connection(&cli, 0)) {
    8579           0 :                 TALLOC_FREE(frame);
    8580           0 :                 return false;
    8581             :         }
    8582             : 
    8583           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8584             : 
    8585           4 :         status = torture_setup_unix_extensions(cli);
    8586           4 :         if (!NT_STATUS_IS_OK(status)) {
    8587           0 :                 TALLOC_FREE(frame);
    8588           0 :                 return false;
    8589             :         }
    8590             : 
    8591           4 :         cli_setatr(cli, fname, 0, 0);
    8592           4 :         cli_posix_unlink(cli, fname);
    8593           4 :         cli_setatr(cli, sname, 0, 0);
    8594           4 :         cli_posix_unlink(cli, sname);
    8595             : 
    8596           4 :         status = cli_ntcreate(cli,
    8597             :                         fname,
    8598             :                         0,
    8599             :                         READ_CONTROL_ACCESS,
    8600             :                         0,
    8601             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8602             :                         FILE_CREATE,
    8603             :                         0x0,
    8604             :                         0x0,
    8605             :                         &fnum,
    8606             :                         NULL);
    8607             : 
    8608           4 :         if (!NT_STATUS_IS_OK(status)) {
    8609           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8610             :                         fname,
    8611             :                         nt_errstr(status));
    8612           0 :                 goto out;
    8613             :         }
    8614             : 
    8615           4 :         status = cli_close(cli, fnum);
    8616           4 :         if (!NT_STATUS_IS_OK(status)) {
    8617           0 :                 printf("close failed (%s)\n",
    8618             :                         nt_errstr(status));
    8619           0 :                 goto out;
    8620             :         }
    8621           4 :         fnum = (uint16_t)-1;
    8622             : 
    8623             :         /* Set an EA on the path. */
    8624           4 :         status = cli_set_ea_path(cli,
    8625             :                                 fname,
    8626             :                                 ea_name,
    8627             :                                 ea_value,
    8628           4 :                                 strlen(ea_value)+1);
    8629             : 
    8630           4 :         if (!NT_STATUS_IS_OK(status)) {
    8631           0 :                 printf("cli_set_ea_path failed (%s)\n",
    8632             :                         nt_errstr(status));
    8633           0 :                 goto out;
    8634             :         }
    8635             : 
    8636             :         /* Now create a symlink. */
    8637           4 :         status = cli_posix_symlink(cli, fname, sname);
    8638           4 :         if (!NT_STATUS_IS_OK(status)) {
    8639           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8640             :                         sname,
    8641             :                         fname,
    8642             :                         nt_errstr(status));
    8643           0 :                 goto out;
    8644             :         }
    8645             : 
    8646             :         /* Get the EA list on the path. Should return value set. */
    8647           4 :         status = cli_get_ea_list_path(cli,
    8648             :                                 fname,
    8649             :                                 frame,
    8650             :                                 &num_eas,
    8651             :                                 &eas);
    8652             : 
    8653           4 :         if (!NT_STATUS_IS_OK(status)) {
    8654           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8655             :                         nt_errstr(status));
    8656           0 :                 goto out;
    8657             :         }
    8658             : 
    8659             :         /* Ensure the EA we set is there. */
    8660           4 :         for (i=0; i<num_eas; i++) {
    8661           4 :                 if (strcmp(eas[i].name, ea_name) == 0 &&
    8662           4 :                                 eas[i].value.length == strlen(ea_value)+1 &&
    8663           4 :                                 memcmp(eas[i].value.data,
    8664             :                                         ea_value,
    8665           4 :                                         eas[i].value.length) == 0) {
    8666           4 :                         break;
    8667             :                 }
    8668             :         }
    8669             : 
    8670           4 :         if (i == num_eas) {
    8671           0 :                 printf("Didn't find EA on pathname %s\n",
    8672             :                         fname);
    8673           0 :                 goto out;
    8674             :         }
    8675             : 
    8676           4 :         num_eas = 0;
    8677           4 :         TALLOC_FREE(eas);
    8678             : 
    8679             :         /* Get the EA list on the symlink. Should return empty list. */
    8680           4 :         status = cli_get_ea_list_path(cli,
    8681             :                                 sname,
    8682             :                                 frame,
    8683             :                                 &num_eas,
    8684             :                                 &eas);
    8685             : 
    8686           4 :         if (!NT_STATUS_IS_OK(status)) {
    8687           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8688             :                         nt_errstr(status));
    8689           0 :                 goto out;
    8690             :         }
    8691             : 
    8692           4 :         if (num_eas != 0) {
    8693           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8694             :                         nt_errstr(status));
    8695           0 :                 goto out;
    8696             :         }
    8697             : 
    8698             :         /* Set an EA on the symlink. Should fail. */
    8699           4 :         status = cli_set_ea_path(cli,
    8700             :                                 sname,
    8701             :                                 ea_name,
    8702             :                                 ea_value,
    8703           4 :                                 strlen(ea_value)+1);
    8704             : 
    8705           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8706           0 :                 printf("cli_set_ea_path on a symlink gave %s. "
    8707             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8708             :                         nt_errstr(status));
    8709           0 :                 goto out;
    8710             :         }
    8711             : 
    8712           4 :         printf("EA symlink test passed\n");
    8713           4 :         correct = true;
    8714             : 
    8715           4 :   out:
    8716             : 
    8717           4 :         if (fnum != (uint16_t)-1) {
    8718           0 :                 cli_close(cli, fnum);
    8719           0 :                 fnum = (uint16_t)-1;
    8720             :         }
    8721             : 
    8722           4 :         cli_setatr(cli, sname, 0, 0);
    8723           4 :         cli_posix_unlink(cli, sname);
    8724           4 :         cli_setatr(cli, fname, 0, 0);
    8725           4 :         cli_posix_unlink(cli, fname);
    8726             : 
    8727           4 :         if (!torture_close_connection(cli)) {
    8728           0 :                 correct = false;
    8729             :         }
    8730             : 
    8731           4 :         TALLOC_FREE(frame);
    8732           4 :         return correct;
    8733             : }
    8734             : 
    8735             : /*
    8736             :   Test POSIX locks are OFD-locks.
    8737             :  */
    8738           4 : static bool run_posix_ofd_lock_test(int dummy)
    8739             : {
    8740           0 :         static struct cli_state *cli;
    8741           4 :         const char *fname = "posix_file";
    8742           4 :         uint16_t fnum1 = (uint16_t)-1;
    8743           4 :         uint16_t fnum2 = (uint16_t)-1;
    8744           4 :         bool correct = false;
    8745           0 :         NTSTATUS status;
    8746           4 :         TALLOC_CTX *frame = NULL;
    8747             : 
    8748           4 :         frame = talloc_stackframe();
    8749             : 
    8750           4 :         printf("Starting POSIX ofd-lock test\n");
    8751             : 
    8752           4 :         if (!torture_open_connection(&cli, 0)) {
    8753           0 :                 TALLOC_FREE(frame);
    8754           0 :                 return false;
    8755             :         }
    8756             : 
    8757           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8758             : 
    8759           4 :         status = torture_setup_unix_extensions(cli);
    8760           4 :         if (!NT_STATUS_IS_OK(status)) {
    8761           0 :                 TALLOC_FREE(frame);
    8762           0 :                 return false;
    8763             :         }
    8764             : 
    8765           4 :         cli_setatr(cli, fname, 0, 0);
    8766           4 :         cli_posix_unlink(cli, fname);
    8767             : 
    8768             :         /* Open the file twice. */
    8769           4 :         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
    8770             :                                 0600, &fnum1);
    8771           4 :         if (!NT_STATUS_IS_OK(status)) {
    8772           0 :                 printf("First POSIX open of %s failed\n", fname);
    8773           0 :                 goto out;
    8774             :         }
    8775             : 
    8776           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
    8777           4 :         if (!NT_STATUS_IS_OK(status)) {
    8778           0 :                 printf("First POSIX open of %s failed\n", fname);
    8779           0 :                 goto out;
    8780             :         }
    8781             : 
    8782             :         /* Set a 0-50 lock on fnum1. */
    8783           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8784           4 :         if (!NT_STATUS_IS_OK(status)) {
    8785           0 :                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
    8786           0 :                 goto out;
    8787             :         }
    8788             : 
    8789             :         /* Set a 60-100 lock on fnum2. */
    8790           4 :         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
    8791           4 :         if (!NT_STATUS_IS_OK(status)) {
    8792           0 :                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
    8793           0 :                 goto out;
    8794             :         }
    8795             : 
    8796             :         /* close fnum1 - 0-50 lock should go away. */
    8797           4 :         status = cli_close(cli, fnum1);
    8798           4 :         if (!NT_STATUS_IS_OK(status)) {
    8799           0 :                 printf("close failed (%s)\n",
    8800             :                         nt_errstr(status));
    8801           0 :                 goto out;
    8802             :         }
    8803           4 :         fnum1 = (uint16_t)-1;
    8804             : 
    8805             :         /* Change the lock context. */
    8806           4 :         cli_setpid(cli, cli_getpid(cli) + 1);
    8807             : 
    8808             :         /* Re-open fnum1. */
    8809           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
    8810           4 :         if (!NT_STATUS_IS_OK(status)) {
    8811           0 :                 printf("Third POSIX open of %s failed\n", fname);
    8812           0 :                 goto out;
    8813             :         }
    8814             : 
    8815             :         /* 60-100 lock should still be there. */
    8816           4 :         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
    8817           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    8818           0 :                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
    8819           0 :                 goto out;
    8820             :         }
    8821             : 
    8822             :         /* 0-50 lock should be gone. */
    8823           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8824           4 :         if (!NT_STATUS_IS_OK(status)) {
    8825           0 :                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
    8826           0 :                 goto out;
    8827             :         }
    8828             : 
    8829           4 :         printf("POSIX OFD lock test passed\n");
    8830           4 :         correct = true;
    8831             : 
    8832           4 :   out:
    8833             : 
    8834           4 :         if (fnum1 != (uint16_t)-1) {
    8835           4 :                 cli_close(cli, fnum1);
    8836           4 :                 fnum1 = (uint16_t)-1;
    8837             :         }
    8838           4 :         if (fnum2 != (uint16_t)-1) {
    8839           4 :                 cli_close(cli, fnum2);
    8840           4 :                 fnum2 = (uint16_t)-1;
    8841             :         }
    8842             : 
    8843           4 :         cli_setatr(cli, fname, 0, 0);
    8844           4 :         cli_posix_unlink(cli, fname);
    8845             : 
    8846           4 :         if (!torture_close_connection(cli)) {
    8847           0 :                 correct = false;
    8848             :         }
    8849             : 
    8850           4 :         TALLOC_FREE(frame);
    8851           4 :         return correct;
    8852             : }
    8853             : 
    8854             : struct posix_blocking_state {
    8855             :         struct tevent_context *ev;
    8856             :         struct cli_state *cli1;
    8857             :         uint16_t fnum1;
    8858             :         struct cli_state *cli2;
    8859             :         uint16_t fnum2;
    8860             :         bool gotblocked;
    8861             :         bool gotecho;
    8862             : };
    8863             : 
    8864             : static void posix_blocking_locked(struct tevent_req *subreq);
    8865             : static void posix_blocking_gotblocked(struct tevent_req *subreq);
    8866             : static void posix_blocking_gotecho(struct tevent_req *subreq);
    8867             : static void posix_blocking_unlocked(struct tevent_req *subreq);
    8868             : 
    8869           4 : static struct tevent_req *posix_blocking_send(
    8870             :         TALLOC_CTX *mem_ctx,
    8871             :         struct tevent_context *ev,
    8872             :         struct cli_state *cli1,
    8873             :         uint16_t fnum1,
    8874             :         struct cli_state *cli2,
    8875             :         uint16_t fnum2)
    8876             : {
    8877           4 :         struct tevent_req *req = NULL, *subreq = NULL;
    8878           4 :         struct posix_blocking_state *state = NULL;
    8879             : 
    8880           4 :         req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
    8881           4 :         if (req == NULL) {
    8882           0 :                 return NULL;
    8883             :         }
    8884           4 :         state->ev = ev;
    8885           4 :         state->cli1 = cli1;
    8886           4 :         state->fnum1 = fnum1;
    8887           4 :         state->cli2 = cli2;
    8888           4 :         state->fnum2 = fnum2;
    8889             : 
    8890           4 :         subreq = cli_posix_lock_send(
    8891             :                 state,
    8892           4 :                 state->ev,
    8893           4 :                 state->cli1,
    8894           4 :                 state->fnum1,
    8895             :                 0,
    8896             :                 1,
    8897             :                 false,
    8898             :                 WRITE_LOCK);
    8899           4 :         if (tevent_req_nomem(subreq, req)) {
    8900           0 :                 return tevent_req_post(req, ev);
    8901             :         }
    8902           4 :         tevent_req_set_callback(subreq, posix_blocking_locked, req);
    8903           4 :         return req;
    8904             : }
    8905             : 
    8906           4 : static void posix_blocking_locked(struct tevent_req *subreq)
    8907             : {
    8908           4 :         struct tevent_req *req = tevent_req_callback_data(
    8909             :                 subreq, struct tevent_req);
    8910           4 :         struct posix_blocking_state *state = tevent_req_data(
    8911             :                 req, struct posix_blocking_state);
    8912           0 :         NTSTATUS status;
    8913             : 
    8914           4 :         status = cli_posix_lock_recv(subreq);
    8915           4 :         TALLOC_FREE(subreq);
    8916           4 :         if (tevent_req_nterror(req, status)) {
    8917           0 :                 return;
    8918             :         }
    8919             : 
    8920           4 :         subreq = cli_posix_lock_send(
    8921             :                 state,
    8922             :                 state->ev,
    8923             :                 state->cli2,
    8924           4 :                 state->fnum2,
    8925             :                 0,
    8926             :                 1,
    8927             :                 true,
    8928             :                 WRITE_LOCK);
    8929           4 :         if (tevent_req_nomem(subreq, req)) {
    8930           0 :                 return;
    8931             :         }
    8932           4 :         tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
    8933             : 
    8934             :         /* Make sure the blocking request is delivered */
    8935           4 :         subreq = cli_echo_send(
    8936             :                 state,
    8937             :                 state->ev,
    8938             :                 state->cli2,
    8939             :                 1,
    8940           4 :                 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
    8941           4 :         if (tevent_req_nomem(subreq, req)) {
    8942           0 :                 return;
    8943             :         }
    8944           4 :         tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
    8945             : }
    8946             : 
    8947           4 : static void posix_blocking_gotblocked(struct tevent_req *subreq)
    8948             : {
    8949           4 :         struct tevent_req *req = tevent_req_callback_data(
    8950             :                 subreq, struct tevent_req);
    8951           4 :         struct posix_blocking_state *state = tevent_req_data(
    8952             :                 req, struct posix_blocking_state);
    8953           0 :         NTSTATUS status;
    8954             : 
    8955           4 :         status = cli_posix_lock_recv(subreq);
    8956           4 :         TALLOC_FREE(subreq);
    8957           4 :         if (tevent_req_nterror(req, status)) {
    8958           0 :                 return;
    8959             :         }
    8960           4 :         if (!state->gotecho) {
    8961           0 :                 printf("blocked req got through before echo\n");
    8962           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8963           0 :                 return;
    8964             :         }
    8965           4 :         tevent_req_done(req);
    8966             : }
    8967             : 
    8968           4 : static void posix_blocking_gotecho(struct tevent_req *subreq)
    8969             : {
    8970           4 :         struct tevent_req *req = tevent_req_callback_data(
    8971             :                 subreq, struct tevent_req);
    8972           4 :         struct posix_blocking_state *state = tevent_req_data(
    8973             :                 req, struct posix_blocking_state);
    8974           0 :         NTSTATUS status;
    8975             : 
    8976           4 :         status = cli_echo_recv(subreq);
    8977           4 :         TALLOC_FREE(subreq);
    8978           4 :         if (tevent_req_nterror(req, status)) {
    8979           0 :                 return;
    8980             :         }
    8981           4 :         if (state->gotblocked) {
    8982           0 :                 printf("blocked req got through before echo\n");
    8983           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8984           0 :                 return;
    8985             :         }
    8986           4 :         state->gotecho = true;
    8987             : 
    8988           4 :         subreq = cli_posix_lock_send(
    8989             :                 state,
    8990             :                 state->ev,
    8991             :                 state->cli1,
    8992           4 :                 state->fnum1,
    8993             :                 0,
    8994             :                 1,
    8995             :                 false,
    8996             :                 UNLOCK_LOCK);
    8997           4 :         if (tevent_req_nomem(subreq, req)) {
    8998           0 :                 return;
    8999             :         }
    9000           4 :         tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
    9001             : }
    9002             : 
    9003           4 : static void posix_blocking_unlocked(struct tevent_req *subreq)
    9004             : {
    9005           4 :         struct tevent_req *req = tevent_req_callback_data(
    9006             :                 subreq, struct tevent_req);
    9007           0 :         NTSTATUS status;
    9008             : 
    9009           4 :         status = cli_posix_lock_recv(subreq);
    9010           4 :         TALLOC_FREE(subreq);
    9011           4 :         if (tevent_req_nterror(req, status)) {
    9012           0 :                 return;
    9013             :         }
    9014             :         /* tevent_req_done in posix_blocking_gotlocked */
    9015             : }
    9016             : 
    9017           4 : static NTSTATUS posix_blocking_recv(struct tevent_req *req)
    9018             : {
    9019           4 :         return tevent_req_simple_recv_ntstatus(req);
    9020             : }
    9021             : 
    9022           4 : static bool run_posix_blocking_lock(int dummy)
    9023             : {
    9024           4 :         struct tevent_context *ev = NULL;
    9025           4 :         struct cli_state *cli1 = NULL, *cli2 = NULL;
    9026           4 :         const char *fname = "posix_blocking";
    9027           4 :         uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
    9028           4 :         struct tevent_req *req = NULL;
    9029           0 :         NTSTATUS status;
    9030           4 :         bool ret = false;
    9031           0 :         bool ok;
    9032             : 
    9033           4 :         printf("Starting posix blocking lock test\n");
    9034             : 
    9035           4 :         ev = samba_tevent_context_init(NULL);
    9036           4 :         if (ev == NULL) {
    9037           0 :                 return false;
    9038             :         }
    9039             : 
    9040           4 :         ok = torture_open_connection(&cli1, 0);
    9041           4 :         if (!ok) {
    9042           0 :                 goto fail;
    9043             :         }
    9044           4 :         ok = torture_open_connection(&cli2, 0);
    9045           4 :         if (!ok) {
    9046           0 :                 goto fail;
    9047             :         }
    9048             : 
    9049           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9050             : 
    9051           4 :         status = torture_setup_unix_extensions(cli1);
    9052           4 :         if (!NT_STATUS_IS_OK(status)) {
    9053           0 :                 return false;
    9054             :         }
    9055             : 
    9056           4 :         status = torture_setup_unix_extensions(cli2);
    9057           4 :         if (!NT_STATUS_IS_OK(status)) {
    9058           0 :                 return false;
    9059             :         }
    9060             : 
    9061           4 :         cli_setatr(cli1, fname, 0, 0);
    9062           4 :         cli_posix_unlink(cli1, fname);
    9063             : 
    9064           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    9065             :                                 0600, &fnum1);
    9066           4 :         if (!NT_STATUS_IS_OK(status)) {
    9067           0 :                 printf("First POSIX open of %s failed: %s\n",
    9068             :                        fname,
    9069             :                        nt_errstr(status));
    9070           0 :                 goto fail;
    9071             :         }
    9072             : 
    9073           4 :         status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
    9074           4 :         if (!NT_STATUS_IS_OK(status)) {
    9075           0 :                 printf("Second POSIX open of %s failed: %s\n",
    9076             :                        fname,
    9077             :                        nt_errstr(status));
    9078           0 :                 goto fail;
    9079             :         }
    9080             : 
    9081           4 :         req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
    9082           4 :         if (req == NULL) {
    9083           0 :                 printf("cli_posix_blocking failed\n");
    9084           0 :                 goto fail;
    9085             :         }
    9086             : 
    9087           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    9088           4 :         if (!ok) {
    9089           0 :                 printf("tevent_req_poll_ntstatus failed: %s\n",
    9090             :                        nt_errstr(status));
    9091           0 :                 goto fail;
    9092             :         }
    9093           4 :         status = posix_blocking_recv(req);
    9094           4 :         TALLOC_FREE(req);
    9095           4 :         if (!NT_STATUS_IS_OK(status)) {
    9096           0 :                 printf("posix_blocking_recv returned %s\n",
    9097             :                        nt_errstr(status));
    9098           0 :                 goto fail;
    9099             :         }
    9100             : 
    9101           4 :         ret = true;
    9102           4 : fail:
    9103             : 
    9104           4 :         if (fnum1 != UINT16_MAX) {
    9105           4 :                 cli_close(cli1, fnum1);
    9106           4 :                 fnum1 = UINT16_MAX;
    9107             :         }
    9108           4 :         if (fnum2 != UINT16_MAX) {
    9109           4 :                 cli_close(cli2, fnum2);
    9110           4 :                 fnum2 = UINT16_MAX;
    9111             :         }
    9112             : 
    9113           4 :         if (cli1 != NULL) {
    9114           4 :                 cli_setatr(cli1, fname, 0, 0);
    9115           4 :                 cli_posix_unlink(cli1, fname);
    9116             :         }
    9117             : 
    9118           4 :         ok = true;
    9119             : 
    9120           4 :         if (cli1 != NULL) {
    9121           4 :                 ok &= torture_close_connection(cli1);
    9122           4 :                 cli1 = NULL;
    9123             :         }
    9124           4 :         if (cli2 != NULL) {
    9125           4 :                 ok &= torture_close_connection(cli2);
    9126           4 :                 cli2 = NULL;
    9127             :         }
    9128             : 
    9129           4 :         if (!ok) {
    9130           0 :                 ret = false;
    9131             :         }
    9132           4 :         TALLOC_FREE(ev);
    9133           4 :         return ret;
    9134             : }
    9135             : 
    9136             : /*
    9137             :   Test POSIX mkdir is case-sensitive.
    9138             :  */
    9139           4 : static bool run_posix_mkdir_test(int dummy)
    9140             : {
    9141           0 :         static struct cli_state *cli;
    9142           4 :         const char *fname_foo = "POSIX_foo";
    9143           4 :         const char *fname_foo_Foo = "POSIX_foo/Foo";
    9144           4 :         const char *fname_foo_foo = "POSIX_foo/foo";
    9145           4 :         const char *fname_Foo = "POSIX_Foo";
    9146           4 :         const char *fname_Foo_Foo = "POSIX_Foo/Foo";
    9147           4 :         const char *fname_Foo_foo = "POSIX_Foo/foo";
    9148           4 :         bool correct = false;
    9149           0 :         NTSTATUS status;
    9150           4 :         TALLOC_CTX *frame = NULL;
    9151           4 :         uint16_t fnum = (uint16_t)-1;
    9152             : 
    9153           4 :         frame = talloc_stackframe();
    9154             : 
    9155           4 :         printf("Starting POSIX mkdir test\n");
    9156             : 
    9157           4 :         if (!torture_open_connection(&cli, 0)) {
    9158           0 :                 TALLOC_FREE(frame);
    9159           0 :                 return false;
    9160             :         }
    9161             : 
    9162           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9163             : 
    9164           4 :         status = torture_setup_unix_extensions(cli);
    9165           4 :         if (!NT_STATUS_IS_OK(status)) {
    9166           0 :                 TALLOC_FREE(frame);
    9167           0 :                 return false;
    9168             :         }
    9169             : 
    9170           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9171           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9172           4 :         cli_posix_rmdir(cli, fname_foo);
    9173             : 
    9174           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9175           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9176           4 :         cli_posix_rmdir(cli, fname_Foo);
    9177             : 
    9178             :         /*
    9179             :          * Create a file POSIX_foo then try
    9180             :          * and use it in a directory path by
    9181             :          * doing mkdir POSIX_foo/bar.
    9182             :          * The mkdir should fail with
    9183             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND
    9184             :          */
    9185             : 
    9186           4 :         status = cli_posix_open(cli,
    9187             :                         fname_foo,
    9188             :                         O_RDWR|O_CREAT,
    9189             :                         0666,
    9190             :                         &fnum);
    9191           4 :         if (!NT_STATUS_IS_OK(status)) {
    9192           0 :                 printf("cli_posix_open of %s failed error %s\n",
    9193             :                         fname_foo,
    9194             :                         nt_errstr(status));
    9195           0 :                 goto out;
    9196             :         }
    9197             : 
    9198           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9199           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9200           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9201             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9202             :                         "%s instead\n",
    9203             :                         fname_foo_foo,
    9204             :                         nt_errstr(status));
    9205           0 :                 goto out;
    9206             :         }
    9207             : 
    9208           4 :         status = cli_close(cli, fnum);
    9209           4 :         if (!NT_STATUS_IS_OK(status)) {
    9210           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    9211           0 :                 goto out;
    9212             :         }
    9213           4 :         fnum = (uint16_t)-1;
    9214             : 
    9215           4 :         status = cli_posix_unlink(cli, fname_foo);
    9216           4 :         if (!NT_STATUS_IS_OK(status)) {
    9217           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
    9218             :                         fname_foo,
    9219             :                         nt_errstr(status));
    9220           0 :                 goto out;
    9221             :         }
    9222             : 
    9223             :         /*
    9224             :          * Now we've deleted everything, posix_mkdir, posix_rmdir,
    9225             :          * posix_open, posix_unlink, on
    9226             :          * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
    9227             :          * not silently create POSIX_foo/foo.
    9228             :          */
    9229             : 
    9230           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9231           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9232           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9233             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9234             :                         "%s instead\n",
    9235             :                         fname_foo_foo,
    9236             :                         nt_errstr(status));
    9237           0 :                 goto out;
    9238             :         }
    9239             : 
    9240           4 :         status = cli_posix_rmdir(cli, fname_foo_foo);
    9241           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9242           0 :                 printf("cli_posix_rmdir of %s should fail with "
    9243             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9244             :                         "%s instead\n",
    9245             :                         fname_foo_foo,
    9246             :                         nt_errstr(status));
    9247           0 :                 goto out;
    9248             :         }
    9249             : 
    9250           4 :         status = cli_posix_open(cli,
    9251             :                         fname_foo_foo,
    9252             :                         O_RDWR|O_CREAT,
    9253             :                         0666,
    9254             :                         &fnum);
    9255           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9256           0 :                 printf("cli_posix_open of %s should fail with "
    9257             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9258             :                         "%s instead\n",
    9259             :                         fname_foo_foo,
    9260             :                         nt_errstr(status));
    9261           0 :                 goto out;
    9262             :         }
    9263             : 
    9264           4 :         status = cli_posix_unlink(cli, fname_foo_foo);
    9265           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9266           0 :                 printf("cli_posix_unlink of %s should fail with "
    9267             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9268             :                         "%s instead\n",
    9269             :                         fname_foo_foo,
    9270             :                         nt_errstr(status));
    9271           0 :                 goto out;
    9272             :         }
    9273             : 
    9274           4 :         status = cli_posix_mkdir(cli, fname_foo, 0777);
    9275           4 :         if (!NT_STATUS_IS_OK(status)) {
    9276           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo);
    9277           0 :                 goto out;
    9278             :         }
    9279             : 
    9280           4 :         status = cli_posix_mkdir(cli, fname_Foo, 0777);
    9281           4 :         if (!NT_STATUS_IS_OK(status)) {
    9282           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
    9283           0 :                 goto out;
    9284             :         }
    9285             : 
    9286           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9287           4 :         if (!NT_STATUS_IS_OK(status)) {
    9288           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
    9289           0 :                 goto out;
    9290             :         }
    9291             : 
    9292           4 :         status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
    9293           4 :         if (!NT_STATUS_IS_OK(status)) {
    9294           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
    9295           0 :                 goto out;
    9296             :         }
    9297             : 
    9298           4 :         status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
    9299           4 :         if (!NT_STATUS_IS_OK(status)) {
    9300           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
    9301           0 :                 goto out;
    9302             :         }
    9303             : 
    9304           4 :         status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
    9305           4 :         if (!NT_STATUS_IS_OK(status)) {
    9306           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
    9307           0 :                 goto out;
    9308             :         }
    9309             : 
    9310           4 :         printf("POSIX mkdir test passed\n");
    9311           4 :         correct = true;
    9312             : 
    9313           4 :   out:
    9314             : 
    9315           4 :         if (fnum != (uint16_t)-1) {
    9316           0 :                 cli_close(cli, fnum);
    9317           0 :                 fnum = (uint16_t)-1;
    9318             :         }
    9319             : 
    9320           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9321           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9322           4 :         cli_posix_rmdir(cli, fname_foo);
    9323             : 
    9324           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9325           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9326           4 :         cli_posix_rmdir(cli, fname_Foo);
    9327             : 
    9328           4 :         if (!torture_close_connection(cli)) {
    9329           0 :                 correct = false;
    9330             :         }
    9331             : 
    9332           4 :         TALLOC_FREE(frame);
    9333           4 :         return correct;
    9334             : }
    9335             : 
    9336             : struct posix_acl_oplock_state {
    9337             :         struct tevent_context *ev;
    9338             :         struct cli_state *cli;
    9339             :         bool *got_break;
    9340             :         bool *acl_ret;
    9341             :         NTSTATUS status;
    9342             : };
    9343             : 
    9344           4 : static void posix_acl_oplock_got_break(struct tevent_req *req)
    9345             : {
    9346           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9347             :                 req, struct posix_acl_oplock_state);
    9348           0 :         uint16_t fnum;
    9349           0 :         uint8_t level;
    9350           0 :         NTSTATUS status;
    9351             : 
    9352           4 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    9353           4 :         TALLOC_FREE(req);
    9354           4 :         if (!NT_STATUS_IS_OK(status)) {
    9355           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    9356             :                        nt_errstr(status));
    9357           0 :                 return;
    9358             :         }
    9359           4 :         *state->got_break = true;
    9360             : 
    9361           4 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    9362             :                                   NO_OPLOCK);
    9363           4 :         if (req == NULL) {
    9364           0 :                 printf("cli_oplock_ack_send failed\n");
    9365           0 :                 return;
    9366             :         }
    9367             : }
    9368             : 
    9369           4 : static void posix_acl_oplock_got_acl(struct tevent_req *req)
    9370             : {
    9371           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9372             :                 req, struct posix_acl_oplock_state);
    9373           4 :         size_t ret_size = 0;
    9374           4 :         char *ret_data = NULL;
    9375             : 
    9376           4 :         state->status = cli_posix_getacl_recv(req,
    9377             :                         state,
    9378             :                         &ret_size,
    9379             :                         &ret_data);
    9380             : 
    9381           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9382           0 :                 printf("cli_posix_getacl_recv returned %s\n",
    9383             :                         nt_errstr(state->status));
    9384             :         }
    9385           4 :         *state->acl_ret = true;
    9386           4 : }
    9387             : 
    9388           4 : static bool run_posix_acl_oplock_test(int dummy)
    9389             : {
    9390           0 :         struct tevent_context *ev;
    9391           0 :         struct cli_state *cli1, *cli2;
    9392           0 :         struct tevent_req *oplock_req, *getacl_req;
    9393           4 :         const char *fname = "posix_acl_oplock";
    9394           0 :         uint16_t fnum;
    9395           4 :         int saved_use_oplocks = use_oplocks;
    9396           0 :         NTSTATUS status;
    9397           4 :         bool correct = true;
    9398           4 :         bool got_break = false;
    9399           4 :         bool acl_ret = false;
    9400             : 
    9401           0 :         struct posix_acl_oplock_state *state;
    9402             : 
    9403           4 :         printf("starting posix_acl_oplock test\n");
    9404             : 
    9405           4 :         if (!torture_open_connection(&cli1, 0)) {
    9406           0 :                 use_level_II_oplocks = false;
    9407           0 :                 use_oplocks = saved_use_oplocks;
    9408           0 :                 return false;
    9409             :         }
    9410             : 
    9411           4 :         if (!torture_open_connection(&cli2, 1)) {
    9412           0 :                 use_level_II_oplocks = false;
    9413           0 :                 use_oplocks = saved_use_oplocks;
    9414           0 :                 return false;
    9415             :         }
    9416             : 
    9417             :         /* Setup posix on cli2 only. */
    9418           4 :         status = torture_setup_unix_extensions(cli2);
    9419           4 :         if (!NT_STATUS_IS_OK(status)) {
    9420           0 :                 return false;
    9421             :         }
    9422             : 
    9423           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9424           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    9425             : 
    9426           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9427             : 
    9428             :         /* Create the file on the Windows connection. */
    9429           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    9430             :                           &fnum);
    9431           4 :         if (!NT_STATUS_IS_OK(status)) {
    9432           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9433           0 :                 return false;
    9434             :         }
    9435             : 
    9436           4 :         status = cli_close(cli1, fnum);
    9437           4 :         if (!NT_STATUS_IS_OK(status)) {
    9438           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    9439           0 :                 return false;
    9440             :         }
    9441             : 
    9442           4 :         cli1->use_oplocks = true;
    9443             : 
    9444             :         /* Open with oplock. */
    9445           4 :         status = cli_ntcreate(cli1,
    9446             :                         fname,
    9447             :                         0,
    9448             :                         FILE_READ_DATA,
    9449             :                         FILE_ATTRIBUTE_NORMAL,
    9450             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    9451             :                         FILE_OPEN,
    9452             :                         0,
    9453             :                         0,
    9454             :                         &fnum,
    9455             :                         NULL);
    9456             : 
    9457           4 :         if (!NT_STATUS_IS_OK(status)) {
    9458           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9459           0 :                 return false;
    9460             :         }
    9461             : 
    9462           4 :         ev = samba_tevent_context_init(talloc_tos());
    9463           4 :         if (ev == NULL) {
    9464           0 :                 printf("tevent_context_init failed\n");
    9465           0 :                 return false;
    9466             :         }
    9467             : 
    9468           4 :         state = talloc_zero(ev, struct posix_acl_oplock_state);
    9469           4 :         if (state == NULL) {
    9470           0 :                 printf("talloc failed\n");
    9471           0 :                 return false;
    9472             :         }
    9473           4 :         state->ev = ev;
    9474           4 :         state->cli = cli1;
    9475           4 :         state->got_break = &got_break;
    9476           4 :         state->acl_ret = &acl_ret;
    9477             : 
    9478           4 :         oplock_req = cli_smb_oplock_break_waiter_send(
    9479             :                 talloc_tos(), ev, cli1);
    9480           4 :         if (oplock_req == NULL) {
    9481           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    9482           0 :                 return false;
    9483             :         }
    9484           4 :         tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
    9485             : 
    9486             :         /* Get ACL on POSIX connection - should break oplock. */
    9487           4 :         getacl_req = cli_posix_getacl_send(talloc_tos(),
    9488             :                                 ev,
    9489             :                                 cli2,
    9490             :                                 fname);
    9491           4 :         if (getacl_req == NULL) {
    9492           0 :                 printf("cli_posix_getacl_send failed\n");
    9493           0 :                 return false;
    9494             :         }
    9495           4 :         tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
    9496             : 
    9497          36 :         while (!got_break || !acl_ret) {
    9498           0 :                 int ret;
    9499          32 :                 ret = tevent_loop_once(ev);
    9500          32 :                 if (ret == -1) {
    9501           0 :                         printf("tevent_loop_once failed: %s\n",
    9502           0 :                                strerror(errno));
    9503           0 :                         return false;
    9504             :                 }
    9505             :         }
    9506             : 
    9507           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9508           0 :                 printf("getacl failed (%s)\n", nt_errstr(state->status));
    9509           0 :                 correct = false;
    9510             :         }
    9511             : 
    9512           4 :         status = cli_close(cli1, fnum);
    9513           4 :         if (!NT_STATUS_IS_OK(status)) {
    9514           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    9515           0 :                 correct = false;
    9516             :         }
    9517             : 
    9518           4 :         status = cli_unlink(cli1,
    9519             :                         fname,
    9520             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9521           4 :         if (!NT_STATUS_IS_OK(status)) {
    9522           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    9523           0 :                 correct = false;
    9524             :         }
    9525             : 
    9526           4 :         if (!torture_close_connection(cli1)) {
    9527           0 :                 correct = false;
    9528             :         }
    9529           4 :         if (!torture_close_connection(cli2)) {
    9530           0 :                 correct = false;
    9531             :         }
    9532             : 
    9533           4 :         if (!got_break) {
    9534           0 :                 correct = false;
    9535             :         }
    9536             : 
    9537           4 :         printf("finished posix acl oplock test\n");
    9538             : 
    9539           4 :         return correct;
    9540             : }
    9541             : 
    9542           4 : static bool run_posix_acl_shareroot_test(int dummy)
    9543             : {
    9544           0 :         struct cli_state *cli;
    9545           0 :         NTSTATUS status;
    9546           4 :         bool correct = false;
    9547           4 :         char *posix_acl = NULL;
    9548           4 :         size_t posix_acl_len = 0;
    9549           4 :         uint16_t num_file_acls = 0;
    9550           4 :         uint16_t num_dir_acls = 0;
    9551           0 :         uint16_t i;
    9552           4 :         uint32_t expected_size = 0;
    9553           4 :         bool got_user = false;
    9554           4 :         bool got_group = false;
    9555           4 :         bool got_other = false;
    9556           4 :         TALLOC_CTX *frame = NULL;
    9557             : 
    9558           4 :         frame = talloc_stackframe();
    9559             : 
    9560           4 :         printf("starting posix_acl_shareroot test\n");
    9561             : 
    9562           4 :         if (!torture_open_connection(&cli, 0)) {
    9563           0 :                 TALLOC_FREE(frame);
    9564           0 :                 return false;
    9565             :         }
    9566             : 
    9567           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9568             : 
    9569           4 :         status = torture_setup_unix_extensions(cli);
    9570           4 :         if (!NT_STATUS_IS_OK(status)) {
    9571           0 :                 printf("Failed to setup unix extensions\n");
    9572           0 :                 goto out;
    9573             :         }
    9574             : 
    9575             :         /* Get the POSIX ACL on the root of the share. */
    9576           4 :         status = cli_posix_getacl(cli,
    9577             :                                 ".",
    9578             :                                 frame,
    9579             :                                 &posix_acl_len,
    9580             :                                 &posix_acl);
    9581             : 
    9582           4 :         if (!NT_STATUS_IS_OK(status)) {
    9583           0 :                 printf("cli_posix_getacl of '.' failed (%s)\n",
    9584             :                         nt_errstr(status));
    9585           0 :                 goto out;
    9586             :         }
    9587             : 
    9588           4 :         if (posix_acl_len < 6 ||
    9589           4 :                         SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
    9590           0 :                 printf("getfacl ., unknown POSIX acl version %u.\n",
    9591           0 :                         (unsigned int)CVAL(posix_acl,0) );
    9592           0 :                 goto out;
    9593             :         }
    9594             : 
    9595           4 :         num_file_acls = SVAL(posix_acl,2);
    9596           4 :         num_dir_acls = SVAL(posix_acl,4);
    9597           4 :         expected_size = SMB_POSIX_ACL_HEADER_SIZE +
    9598           4 :                                 SMB_POSIX_ACL_ENTRY_SIZE*
    9599           4 :                                 (num_file_acls+num_dir_acls);
    9600             : 
    9601           4 :         if (posix_acl_len != expected_size) {
    9602           0 :                 printf("incorrect POSIX acl buffer size "
    9603             :                         "(should be %u, was %u).\n",
    9604             :                         (unsigned int)expected_size,
    9605             :                         (unsigned int)posix_acl_len);
    9606           0 :                 goto out;
    9607             :         }
    9608             : 
    9609             :         /*
    9610             :          * We don't need to know what the ACL's are
    9611             :          * we just need to know we have at least 3
    9612             :          * file entries (u,g,o).
    9613             :          */
    9614             : 
    9615          16 :         for (i = 0; i < num_file_acls; i++) {
    9616          12 :                 unsigned char tagtype =
    9617          12 :                         CVAL(posix_acl,
    9618             :                                 SMB_POSIX_ACL_HEADER_SIZE+
    9619             :                                 (i*SMB_POSIX_ACL_ENTRY_SIZE));
    9620             : 
    9621          12 :                 switch(tagtype) {
    9622           4 :                         case SMB_POSIX_ACL_USER_OBJ:
    9623           4 :                                 got_user = true;
    9624           4 :                                 break;
    9625           4 :                         case SMB_POSIX_ACL_GROUP_OBJ:
    9626           4 :                                 got_group = true;
    9627           4 :                                 break;
    9628           4 :                         case SMB_POSIX_ACL_OTHER:
    9629           4 :                                 got_other = true;
    9630           4 :                                 break;
    9631           0 :                         default:
    9632           0 :                                 break;
    9633             :                 }
    9634             :         }
    9635             : 
    9636           4 :         if (!got_user) {
    9637           0 :                 printf("Missing user entry\n");
    9638           0 :                 goto out;
    9639             :         }
    9640             : 
    9641           4 :         if (!got_group) {
    9642           0 :                 printf("Missing group entry\n");
    9643           0 :                 goto out;
    9644             :         }
    9645             : 
    9646           4 :         if (!got_other) {
    9647           0 :                 printf("Missing other entry\n");
    9648           0 :                 goto out;
    9649             :         }
    9650             : 
    9651           4 :         correct = true;
    9652             : 
    9653           4 :   out:
    9654             : 
    9655           4 :         if (!torture_close_connection(cli)) {
    9656           0 :                 correct = false;
    9657             :         }
    9658             : 
    9659           4 :         printf("finished posix acl shareroot test\n");
    9660           4 :         TALLOC_FREE(frame);
    9661             : 
    9662           4 :         return correct;
    9663             : }
    9664             : 
    9665             : static uint32_t open_attrs_table[] = {
    9666             :                 FILE_ATTRIBUTE_NORMAL,
    9667             :                 FILE_ATTRIBUTE_ARCHIVE,
    9668             :                 FILE_ATTRIBUTE_READONLY,
    9669             :                 FILE_ATTRIBUTE_HIDDEN,
    9670             :                 FILE_ATTRIBUTE_SYSTEM,
    9671             : 
    9672             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
    9673             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
    9674             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
    9675             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9676             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9677             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9678             : 
    9679             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9680             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9681             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9682             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
    9683             : };
    9684             : 
    9685             : struct trunc_open_results {
    9686             :         unsigned int num;
    9687             :         uint32_t init_attr;
    9688             :         uint32_t trunc_attr;
    9689             :         uint32_t result_attr;
    9690             : };
    9691             : 
    9692             : static struct trunc_open_results attr_results[] = {
    9693             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9694             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9695             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9696             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9697             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9698             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9699             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9700             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9701             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9702             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9703             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9704             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9705             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9706             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9707             :         { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9708             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9709             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9710             :         { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9711             :         { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
    9712             :         { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
    9713             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9714             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9715             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9716             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9717             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9718             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
    9719             : };
    9720             : 
    9721           0 : static bool run_openattrtest(int dummy)
    9722             : {
    9723           0 :         static struct cli_state *cli1;
    9724           0 :         const char *fname = "\\openattr.file";
    9725           0 :         uint16_t fnum1;
    9726           0 :         bool correct = True;
    9727           0 :         uint32_t attr;
    9728           0 :         unsigned int i, j, k, l;
    9729           0 :         NTSTATUS status;
    9730             : 
    9731           0 :         printf("starting open attr test\n");
    9732             : 
    9733           0 :         if (!torture_open_connection(&cli1, 0)) {
    9734           0 :                 return False;
    9735             :         }
    9736             : 
    9737           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9738             : 
    9739           0 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
    9740           0 :                 cli_setatr(cli1, fname, 0, 0);
    9741           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9742             : 
    9743           0 :                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
    9744             :                                        open_attrs_table[i], FILE_SHARE_NONE,
    9745             :                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    9746           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9747           0 :                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9748           0 :                         return False;
    9749             :                 }
    9750             : 
    9751           0 :                 status = cli_close(cli1, fnum1);
    9752           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9753           0 :                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9754           0 :                         return False;
    9755             :                 }
    9756             : 
    9757           0 :                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
    9758           0 :                         status = cli_ntcreate(cli1, fname, 0,
    9759             :                                               FILE_READ_DATA|FILE_WRITE_DATA,
    9760             :                                               open_attrs_table[j],
    9761             :                                               FILE_SHARE_NONE, FILE_OVERWRITE,
    9762             :                                               0, 0, &fnum1, NULL);
    9763           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9764           0 :                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9765           0 :                                         if (attr_results[l].num == k) {
    9766           0 :                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
    9767             :                                                                 k, open_attrs_table[i],
    9768             :                                                                 open_attrs_table[j],
    9769             :                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
    9770           0 :                                                 correct = False;
    9771             :                                         }
    9772             :                                 }
    9773             : 
    9774           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    9775           0 :                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
    9776             :                                                         k, open_attrs_table[i], open_attrs_table[j],
    9777             :                                                         nt_errstr(status));
    9778           0 :                                         correct = False;
    9779             :                                 }
    9780             : #if 0
    9781             :                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
    9782             : #endif
    9783           0 :                                 k++;
    9784           0 :                                 continue;
    9785             :                         }
    9786             : 
    9787           0 :                         status = cli_close(cli1, fnum1);
    9788           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9789           0 :                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
    9790           0 :                                 return False;
    9791             :                         }
    9792             : 
    9793           0 :                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
    9794           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9795           0 :                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
    9796           0 :                                 return False;
    9797             :                         }
    9798             : 
    9799             : #if 0
    9800             :                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
    9801             :                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
    9802             : #endif
    9803             : 
    9804           0 :                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9805           0 :                                 if (attr_results[l].num == k) {
    9806           0 :                                         if (attr != attr_results[l].result_attr ||
    9807           0 :                                                         open_attrs_table[i] != attr_results[l].init_attr ||
    9808           0 :                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
    9809           0 :                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
    9810             :                                                 open_attrs_table[i],
    9811             :                                                 open_attrs_table[j],
    9812             :                                                 (unsigned int)attr,
    9813             :                                                 attr_results[l].result_attr);
    9814           0 :                                                 correct = False;
    9815             :                                         }
    9816           0 :                                         break;
    9817             :                                 }
    9818             :                         }
    9819           0 :                         k++;
    9820             :                 }
    9821             :         }
    9822             : 
    9823           0 :         cli_setatr(cli1, fname, 0, 0);
    9824           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9825             : 
    9826           0 :         printf("open attr test %s.\n", correct ? "passed" : "failed");
    9827             : 
    9828           0 :         if (!torture_close_connection(cli1)) {
    9829           0 :                 correct = False;
    9830             :         }
    9831           0 :         return correct;
    9832             : }
    9833             : 
    9834           0 : static NTSTATUS list_fn(struct file_info *finfo,
    9835             :                     const char *name, void *state)
    9836             : {
    9837           0 :         int *matched = (int *)state;
    9838           0 :         if (matched != NULL) {
    9839           0 :                 *matched += 1;
    9840             :         }
    9841           0 :         return NT_STATUS_OK;
    9842             : }
    9843             : 
    9844             : /*
    9845             :   test directory listing speed
    9846             :  */
    9847           5 : static bool run_dirtest(int dummy)
    9848             : {
    9849           0 :         int i;
    9850           0 :         static struct cli_state *cli;
    9851           0 :         uint16_t fnum;
    9852           0 :         struct timeval core_start;
    9853           5 :         bool correct = True;
    9854           0 :         int matched;
    9855             : 
    9856           5 :         printf("starting directory test\n");
    9857             : 
    9858           5 :         if (!torture_open_connection(&cli, 0)) {
    9859           0 :                 return False;
    9860             :         }
    9861             : 
    9862           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9863             : 
    9864           5 :         srandom(0);
    9865         505 :         for (i=0;i<torture_numops;i++) {
    9866           0 :                 fstring fname;
    9867         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9868         500 :                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
    9869           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
    9870           0 :                         return False;
    9871             :                 }
    9872         500 :                 cli_close(cli, fnum);
    9873             :         }
    9874             : 
    9875           5 :         core_start = timeval_current();
    9876             : 
    9877           5 :         matched = 0;
    9878           5 :         cli_list(cli, "a*.*", 0, list_fn, &matched);
    9879           5 :         printf("Matched %d\n", matched);
    9880             : 
    9881           5 :         matched = 0;
    9882           5 :         cli_list(cli, "b*.*", 0, list_fn, &matched);
    9883           5 :         printf("Matched %d\n", matched);
    9884             : 
    9885           5 :         matched = 0;
    9886           5 :         cli_list(cli, "xyzabc", 0, list_fn, &matched);
    9887           5 :         printf("Matched %d\n", matched);
    9888             : 
    9889           5 :         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
    9890             : 
    9891           5 :         srandom(0);
    9892         505 :         for (i=0;i<torture_numops;i++) {
    9893           0 :                 fstring fname;
    9894         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9895         500 :                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9896             :         }
    9897             : 
    9898           5 :         if (!torture_close_connection(cli)) {
    9899           0 :                 correct = False;
    9900             :         }
    9901             : 
    9902           5 :         printf("finished dirtest\n");
    9903             : 
    9904           5 :         return correct;
    9905             : }
    9906             : 
    9907           0 : static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
    9908             :                    void *state)
    9909             : {
    9910           0 :         struct cli_state *pcli = (struct cli_state *)state;
    9911           0 :         fstring fname;
    9912           0 :         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
    9913             : 
    9914           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
    9915           0 :                 return NT_STATUS_OK;
    9916             : 
    9917           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    9918           0 :                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
    9919           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
    9920             :         } else {
    9921           0 :                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
    9922           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
    9923             :         }
    9924           0 :         return NT_STATUS_OK;
    9925             : }
    9926             : 
    9927             : 
    9928             : /*
    9929             :    send a raw ioctl - used by the torture code
    9930             : */
    9931      327690 : static NTSTATUS cli_raw_ioctl(struct cli_state *cli,
    9932             :                               uint16_t fnum,
    9933             :                               uint32_t code,
    9934             :                               DATA_BLOB *blob)
    9935             : {
    9936           0 :         uint16_t vwv[3];
    9937           0 :         NTSTATUS status;
    9938             : 
    9939      327690 :         PUSH_LE_U16(vwv + 0, 0, fnum);
    9940      327690 :         PUSH_LE_U16(vwv + 1, 0, code >> 16);
    9941      327690 :         PUSH_LE_U16(vwv + 2, 0, (code & 0xFFFF));
    9942             : 
    9943      327690 :         status = cli_smb(talloc_tos(),
    9944             :                          cli,
    9945             :                          SMBioctl,
    9946             :                          0,
    9947             :                          3,
    9948             :                          vwv,
    9949             :                          0,
    9950             :                          NULL,
    9951             :                          NULL,
    9952             :                          0,
    9953             :                          NULL,
    9954             :                          NULL,
    9955             :                          NULL,
    9956             :                          NULL);
    9957      327690 :         if (!NT_STATUS_IS_OK(status)) {
    9958      327682 :                 return status;
    9959             :         }
    9960           8 :         *blob = data_blob_null;
    9961           8 :         return NT_STATUS_OK;
    9962             : }
    9963             : 
    9964             : /*
    9965             :   sees what IOCTLs are supported
    9966             :  */
    9967           5 : bool torture_ioctl_test(int dummy)
    9968             : {
    9969           0 :         static struct cli_state *cli;
    9970           0 :         uint16_t device, function;
    9971           0 :         uint16_t fnum;
    9972           5 :         const char *fname = "\\ioctl.dat";
    9973           0 :         DATA_BLOB blob;
    9974           0 :         NTSTATUS status;
    9975             : 
    9976           5 :         if (!torture_open_connection(&cli, 0)) {
    9977           0 :                 return False;
    9978             :         }
    9979             : 
    9980           5 :         printf("starting ioctl test\n");
    9981             : 
    9982           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9983             : 
    9984           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    9985           5 :         if (!NT_STATUS_IS_OK(status)) {
    9986           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9987           0 :                 return False;
    9988             :         }
    9989             : 
    9990           5 :         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
    9991           5 :         printf("ioctl device info: %s\n", nt_errstr(status));
    9992             : 
    9993           5 :         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
    9994           5 :         printf("ioctl job info: %s\n", nt_errstr(status));
    9995             : 
    9996        1285 :         for (device=0;device<0x100;device++) {
    9997        1280 :                 printf("ioctl test with device = 0x%x\n", device);
    9998      328960 :                 for (function=0;function<0x100;function++) {
    9999      327680 :                         uint32_t code = (device<<16) | function;
   10000             : 
   10001      327680 :                         status = cli_raw_ioctl(cli, fnum, code, &blob);
   10002             : 
   10003      327680 :                         if (NT_STATUS_IS_OK(status)) {
   10004           4 :                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
   10005           4 :                                        (int)blob.length);
   10006           4 :                                 data_blob_free(&blob);
   10007             :                         }
   10008             :                 }
   10009             :         }
   10010             : 
   10011           5 :         if (!torture_close_connection(cli)) {
   10012           0 :                 return False;
   10013             :         }
   10014             : 
   10015           5 :         return True;
   10016             : }
   10017             : 
   10018             : 
   10019             : /*
   10020             :   tries variants of chkpath
   10021             :  */
   10022           5 : bool torture_chkpath_test(int dummy)
   10023             : {
   10024           0 :         static struct cli_state *cli;
   10025           0 :         uint16_t fnum;
   10026           0 :         bool ret;
   10027           0 :         NTSTATUS status;
   10028             : 
   10029           5 :         if (!torture_open_connection(&cli, 0)) {
   10030           0 :                 return False;
   10031             :         }
   10032             : 
   10033           5 :         printf("starting chkpath test\n");
   10034             : 
   10035             :         /* cleanup from an old run */
   10036           5 :         torture_deltree(cli, "\\chkpath.dir");
   10037             : 
   10038           5 :         status = cli_mkdir(cli, "\\chkpath.dir");
   10039           5 :         if (!NT_STATUS_IS_OK(status)) {
   10040           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   10041           0 :                 return False;
   10042             :         }
   10043             : 
   10044           5 :         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
   10045           5 :         if (!NT_STATUS_IS_OK(status)) {
   10046           0 :                 printf("mkdir2 failed : %s\n", nt_errstr(status));
   10047           0 :                 return False;
   10048             :         }
   10049             : 
   10050           5 :         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
   10051             :                           DENY_NONE, &fnum);
   10052           5 :         if (!NT_STATUS_IS_OK(status)) {
   10053           0 :                 printf("open1 failed (%s)\n", nt_errstr(status));
   10054           0 :                 return False;
   10055             :         }
   10056           5 :         cli_close(cli, fnum);
   10057             : 
   10058           5 :         status = cli_chkpath(cli, "\\chkpath.dir");
   10059           5 :         if (!NT_STATUS_IS_OK(status)) {
   10060           0 :                 printf("chkpath1 failed: %s\n", nt_errstr(status));
   10061           0 :                 ret = False;
   10062             :         }
   10063             : 
   10064           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
   10065           5 :         if (!NT_STATUS_IS_OK(status)) {
   10066           0 :                 printf("chkpath2 failed: %s\n", nt_errstr(status));
   10067           0 :                 ret = False;
   10068             :         }
   10069             : 
   10070           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
   10071           5 :         if (!NT_STATUS_IS_OK(status)) {
   10072           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10073           5 :                                   NT_STATUS_NOT_A_DIRECTORY);
   10074             :         } else {
   10075           0 :                 printf("* chkpath on a file should fail\n");
   10076           0 :                 ret = False;
   10077             :         }
   10078             : 
   10079           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
   10080           5 :         if (!NT_STATUS_IS_OK(status)) {
   10081           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
   10082           5 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
   10083             :         } else {
   10084           0 :                 printf("* chkpath on a non existent file should fail\n");
   10085           0 :                 ret = False;
   10086             :         }
   10087             : 
   10088           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
   10089           5 :         if (!NT_STATUS_IS_OK(status)) {
   10090           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10091           5 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
   10092             :         } else {
   10093           0 :                 printf("* chkpath on a non existent component should fail\n");
   10094           0 :                 ret = False;
   10095             :         }
   10096             : 
   10097           5 :         torture_deltree(cli, "\\chkpath.dir");
   10098             : 
   10099           5 :         if (!torture_close_connection(cli)) {
   10100           0 :                 return False;
   10101             :         }
   10102             : 
   10103           5 :         return ret;
   10104             : }
   10105             : 
   10106           0 : static bool run_eatest(int dummy)
   10107             : {
   10108           0 :         static struct cli_state *cli;
   10109           0 :         const char *fname = "\\eatest.txt";
   10110           0 :         bool correct = True;
   10111           0 :         uint16_t fnum;
   10112           0 :         size_t i, num_eas;
   10113           0 :         struct ea_struct *ea_list = NULL;
   10114           0 :         TALLOC_CTX *mem_ctx = talloc_init("eatest");
   10115           0 :         NTSTATUS status;
   10116             : 
   10117           0 :         printf("starting eatest\n");
   10118             : 
   10119           0 :         if (!torture_open_connection(&cli, 0)) {
   10120           0 :                 talloc_destroy(mem_ctx);
   10121           0 :                 return False;
   10122             :         }
   10123             : 
   10124           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10125             : 
   10126           0 :         status = cli_ntcreate(cli, fname, 0,
   10127             :                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10128             :                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
   10129             :                               0x4044, 0, &fnum, NULL);
   10130           0 :         if (!NT_STATUS_IS_OK(status)) {
   10131           0 :                 printf("open failed - %s\n", nt_errstr(status));
   10132           0 :                 talloc_destroy(mem_ctx);
   10133           0 :                 return False;
   10134             :         }
   10135             : 
   10136           0 :         for (i = 0; i < 10; i++) {
   10137           0 :                 fstring ea_name, ea_val;
   10138             : 
   10139           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
   10140           0 :                 memset(ea_val, (char)i+1, i+1);
   10141           0 :                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
   10142           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10143           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10144             :                                nt_errstr(status));
   10145           0 :                         talloc_destroy(mem_ctx);
   10146           0 :                         return False;
   10147             :                 }
   10148             :         }
   10149             : 
   10150           0 :         cli_close(cli, fnum);
   10151           0 :         for (i = 0; i < 10; i++) {
   10152           0 :                 fstring ea_name, ea_val;
   10153             : 
   10154           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
   10155           0 :                 memset(ea_val, (char)i+1, i+1);
   10156           0 :                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
   10157           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10158           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10159             :                                nt_errstr(status));
   10160           0 :                         talloc_destroy(mem_ctx);
   10161           0 :                         return False;
   10162             :                 }
   10163             :         }
   10164             : 
   10165           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10166           0 :         if (!NT_STATUS_IS_OK(status)) {
   10167           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10168           0 :                 correct = False;
   10169             :         }
   10170             : 
   10171           0 :         printf("num_eas = %d\n", (int)num_eas);
   10172             : 
   10173           0 :         if (num_eas != 20) {
   10174           0 :                 printf("Should be 20 EA's stored... failing.\n");
   10175           0 :                 correct = False;
   10176             :         }
   10177             : 
   10178           0 :         for (i = 0; i < num_eas; i++) {
   10179           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10180           0 :                 dump_data(0, ea_list[i].value.data,
   10181           0 :                           ea_list[i].value.length);
   10182             :         }
   10183             : 
   10184             :         /* Setting EA's to zero length deletes them. Test this */
   10185           0 :         printf("Now deleting all EA's - case independent....\n");
   10186             : 
   10187             : #if 1
   10188           0 :         cli_set_ea_path(cli, fname, "", "", 0);
   10189             : #else
   10190             :         for (i = 0; i < 20; i++) {
   10191             :                 fstring ea_name;
   10192             :                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
   10193             :                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
   10194             :                 if (!NT_STATUS_IS_OK(status)) {
   10195             :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10196             :                                nt_errstr(status));
   10197             :                         talloc_destroy(mem_ctx);
   10198             :                         return False;
   10199             :                 }
   10200             :         }
   10201             : #endif
   10202             : 
   10203           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10204           0 :         if (!NT_STATUS_IS_OK(status)) {
   10205           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10206           0 :                 correct = False;
   10207             :         }
   10208             : 
   10209           0 :         printf("num_eas = %d\n", (int)num_eas);
   10210           0 :         for (i = 0; i < num_eas; i++) {
   10211           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10212           0 :                 dump_data(0, ea_list[i].value.data,
   10213           0 :                           ea_list[i].value.length);
   10214             :         }
   10215             : 
   10216           0 :         if (num_eas != 0) {
   10217           0 :                 printf("deleting EA's failed.\n");
   10218           0 :                 correct = False;
   10219             :         }
   10220             : 
   10221             :         /* Try and delete a non existent EA. */
   10222           0 :         status = cli_set_ea_path(cli, fname, "foo", "", 0);
   10223           0 :         if (!NT_STATUS_IS_OK(status)) {
   10224           0 :                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
   10225             :                        nt_errstr(status));
   10226           0 :                 correct = False;
   10227             :         }
   10228             : 
   10229           0 :         talloc_destroy(mem_ctx);
   10230           0 :         if (!torture_close_connection(cli)) {
   10231           0 :                 correct = False;
   10232             :         }
   10233             : 
   10234           0 :         return correct;
   10235             : }
   10236             : 
   10237           0 : static bool run_dirtest1(int dummy)
   10238             : {
   10239           0 :         int i;
   10240           0 :         static struct cli_state *cli;
   10241           0 :         uint16_t fnum;
   10242           0 :         int num_seen;
   10243           0 :         bool correct = True;
   10244             : 
   10245           0 :         printf("starting directory test\n");
   10246             : 
   10247           0 :         if (!torture_open_connection(&cli, 0)) {
   10248           0 :                 return False;
   10249             :         }
   10250             : 
   10251           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10252             : 
   10253           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10254           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10255           0 :         cli_rmdir(cli, "\\LISTDIR");
   10256           0 :         cli_mkdir(cli, "\\LISTDIR");
   10257             : 
   10258             :         /* Create 1000 files and 1000 directories. */
   10259           0 :         for (i=0;i<1000;i++) {
   10260           0 :                 fstring fname;
   10261           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
   10262           0 :                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10263             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
   10264             :                                    0, 0, &fnum, NULL))) {
   10265           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10266           0 :                         return False;
   10267             :                 }
   10268           0 :                 cli_close(cli, fnum);
   10269             :         }
   10270           0 :         for (i=0;i<1000;i++) {
   10271           0 :                 fstring fname;
   10272           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
   10273           0 :                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
   10274           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10275           0 :                         return False;
   10276             :                 }
   10277             :         }
   10278             : 
   10279             :         /* Now ensure that doing an old list sees both files and directories. */
   10280           0 :         num_seen = 0;
   10281           0 :         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10282           0 :         printf("num_seen = %d\n", num_seen );
   10283             :         /* We should see 100 files + 1000 directories + . and .. */
   10284           0 :         if (num_seen != 2002)
   10285           0 :                 correct = False;
   10286             : 
   10287             :         /* Ensure if we have the "must have" bits we only see the
   10288             :          * relevant entries.
   10289             :          */
   10290           0 :         num_seen = 0;
   10291           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10292           0 :         printf("num_seen = %d\n", num_seen );
   10293           0 :         if (num_seen != 1002)
   10294           0 :                 correct = False;
   10295             : 
   10296           0 :         num_seen = 0;
   10297           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10298           0 :         printf("num_seen = %d\n", num_seen );
   10299           0 :         if (num_seen != 1000)
   10300           0 :                 correct = False;
   10301             : 
   10302             :         /* Delete everything. */
   10303           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10304           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10305           0 :         cli_rmdir(cli, "\\LISTDIR");
   10306             : 
   10307             : #if 0
   10308             :         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
   10309             :         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
   10310             :         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
   10311             : #endif
   10312             : 
   10313           0 :         if (!torture_close_connection(cli)) {
   10314           0 :                 correct = False;
   10315             :         }
   10316             : 
   10317           0 :         printf("finished dirtest1\n");
   10318             : 
   10319           0 :         return correct;
   10320             : }
   10321             : 
   10322           0 : static bool run_error_map_extract(int dummy) {
   10323             : 
   10324           0 :         static struct cli_state *c_dos;
   10325           0 :         static struct cli_state *c_nt;
   10326           0 :         NTSTATUS status;
   10327             : 
   10328           0 :         uint32_t error;
   10329             : 
   10330           0 :         uint32_t errnum;
   10331           0 :         uint8_t errclass;
   10332             : 
   10333           0 :         NTSTATUS nt_status;
   10334             : 
   10335           0 :         fstring user;
   10336             : 
   10337             :         /* NT-Error connection */
   10338             : 
   10339           0 :         disable_spnego = true;
   10340           0 :         if (!(c_nt = open_nbt_connection())) {
   10341           0 :                 disable_spnego = false;
   10342           0 :                 return False;
   10343             :         }
   10344           0 :         disable_spnego = false;
   10345             : 
   10346           0 :         status = smbXcli_negprot(c_nt->conn,
   10347           0 :                                  c_nt->timeout,
   10348             :                                  PROTOCOL_CORE,
   10349             :                                  PROTOCOL_NT1,
   10350             :                                  NULL,
   10351             :                                  NULL,
   10352             :                                  NULL);
   10353             : 
   10354           0 :         if (!NT_STATUS_IS_OK(status)) {
   10355           0 :                 printf("%s rejected the NT-error negprot (%s)\n", host,
   10356             :                        nt_errstr(status));
   10357           0 :                 cli_shutdown(c_nt);
   10358           0 :                 return False;
   10359             :         }
   10360             : 
   10361           0 :         status = cli_session_setup_anon(c_nt);
   10362           0 :         if (!NT_STATUS_IS_OK(status)) {
   10363           0 :                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
   10364           0 :                 return False;
   10365             :         }
   10366             : 
   10367             :         /* DOS-Error connection */
   10368             : 
   10369           0 :         disable_spnego = true;
   10370           0 :         force_dos_errors = true;
   10371           0 :         if (!(c_dos = open_nbt_connection())) {
   10372           0 :                 disable_spnego = false;
   10373           0 :                 force_dos_errors = false;
   10374           0 :                 return False;
   10375             :         }
   10376           0 :         disable_spnego = false;
   10377           0 :         force_dos_errors = false;
   10378             : 
   10379           0 :         status = smbXcli_negprot(c_dos->conn,
   10380           0 :                                  c_dos->timeout,
   10381             :                                  PROTOCOL_CORE,
   10382             :                                  PROTOCOL_NT1,
   10383             :                                  NULL,
   10384             :                                  NULL,
   10385             :                                  NULL);
   10386           0 :         if (!NT_STATUS_IS_OK(status)) {
   10387           0 :                 printf("%s rejected the DOS-error negprot (%s)\n", host,
   10388             :                        nt_errstr(status));
   10389           0 :                 cli_shutdown(c_dos);
   10390           0 :                 return False;
   10391             :         }
   10392             : 
   10393           0 :         status = cli_session_setup_anon(c_dos);
   10394           0 :         if (!NT_STATUS_IS_OK(status)) {
   10395           0 :                 printf("%s rejected the DOS-error initial session setup (%s)\n",
   10396             :                         host, nt_errstr(status));
   10397           0 :                 return False;
   10398             :         }
   10399             : 
   10400           0 :         c_nt->map_dos_errors = false;
   10401           0 :         c_dos->map_dos_errors = false;
   10402             : 
   10403           0 :         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
   10404           0 :                 struct cli_credentials *user_creds = NULL;
   10405             : 
   10406           0 :                 fstr_sprintf(user, "%X", error);
   10407             : 
   10408           0 :                 user_creds = cli_session_creds_init(talloc_tos(),
   10409             :                                                     user,
   10410             :                                                     workgroup,
   10411             :                                                     NULL, /* realm */
   10412             :                                                     password,
   10413             :                                                     false, /* use_kerberos */
   10414             :                                                     false, /* fallback_after_kerberos */
   10415             :                                                     false, /* use_ccache */
   10416             :                                                     false); /* password_is_nt_hash */
   10417           0 :                 if (user_creds == NULL) {
   10418           0 :                         printf("cli_session_creds_init(%s) failed\n", user);
   10419           0 :                         return false;
   10420             :                 }
   10421             : 
   10422           0 :                 status = cli_session_setup_creds(c_nt, user_creds);
   10423           0 :                 if (NT_STATUS_IS_OK(status)) {
   10424           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10425             :                 }
   10426             : 
   10427             :                 /* Case #1: 32-bit NT errors */
   10428           0 :                 if (!NT_STATUS_IS_DOS(status)) {
   10429           0 :                         nt_status = status;
   10430             :                 } else {
   10431           0 :                         printf("/** Dos error on NT connection! (%s) */\n", 
   10432             :                                nt_errstr(status));
   10433           0 :                         nt_status = NT_STATUS(0xc0000000);
   10434             :                 }
   10435             : 
   10436           0 :                 status = cli_session_setup_creds(c_dos, user_creds);
   10437           0 :                 if (NT_STATUS_IS_OK(status)) {
   10438           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10439             :                 }
   10440             : 
   10441             :                 /* Case #1: 32-bit NT errors */
   10442           0 :                 if (NT_STATUS_IS_DOS(status)) {
   10443           0 :                         printf("/** NT error on DOS connection! (%s) */\n", 
   10444             :                                nt_errstr(status));
   10445           0 :                         errnum = errclass = 0;
   10446             :                 } else {
   10447           0 :                         errclass = NT_STATUS_DOS_CLASS(status);
   10448           0 :                         errnum = NT_STATUS_DOS_CODE(status);
   10449             :                 }
   10450             : 
   10451           0 :                 if (NT_STATUS_V(nt_status) != error) { 
   10452           0 :                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
   10453           0 :                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
   10454           0 :                                get_nt_error_c_code(talloc_tos(), nt_status));
   10455             :                 }
   10456             : 
   10457           0 :                 printf("\t{%s,\t%s,\t%s},\n", 
   10458             :                        smb_dos_err_class(errclass), 
   10459             :                        smb_dos_err_name(errclass, errnum), 
   10460           0 :                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
   10461             : 
   10462           0 :                 TALLOC_FREE(user_creds);
   10463             :         }
   10464           0 :         return True;
   10465             : }
   10466             : 
   10467           0 : static bool run_sesssetup_bench(int dummy)
   10468             : {
   10469           0 :         static struct cli_state *c;
   10470           0 :         const char *fname = "\\file.dat";
   10471           0 :         uint16_t fnum;
   10472           0 :         NTSTATUS status;
   10473           0 :         int i;
   10474             : 
   10475           0 :         if (!torture_open_connection(&c, 0)) {
   10476           0 :                 return false;
   10477             :         }
   10478             : 
   10479           0 :         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10480             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10481             :                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
   10482           0 :         if (!NT_STATUS_IS_OK(status)) {
   10483           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10484           0 :                 return false;
   10485             :         }
   10486             : 
   10487           0 :         for (i=0; i<torture_numops; i++) {
   10488           0 :                 status = cli_session_setup_creds(c, torture_creds);
   10489           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10490           0 :                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
   10491             :                                  __location__, nt_errstr(status));
   10492           0 :                         return false;
   10493             :                 }
   10494             : 
   10495           0 :                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
   10496             : 
   10497           0 :                 status = cli_ulogoff(c);
   10498           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10499           0 :                         d_printf("(%s) cli_ulogoff failed: %s\n",
   10500             :                                  __location__, nt_errstr(status));
   10501           0 :                         return false;
   10502             :                 }
   10503             :         }
   10504             : 
   10505           0 :         return true;
   10506             : }
   10507             : 
   10508           9 : static bool subst_test(const char *str, const char *user, const char *domain,
   10509             :                        uid_t uid, gid_t gid, const char *expected)
   10510             : {
   10511           9 :         char *subst;
   10512           9 :         bool result = true;
   10513             : 
   10514           9 :         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
   10515             : 
   10516           9 :         if (strcmp(subst, expected) != 0) {
   10517           0 :                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
   10518             :                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
   10519             :                        expected);
   10520           0 :                 result = false;
   10521             :         }
   10522             : 
   10523           9 :         TALLOC_FREE(subst);
   10524           9 :         return result;
   10525             : }
   10526             : 
   10527           5 : static void chain1_open_completion(struct tevent_req *req)
   10528             : {
   10529           0 :         uint16_t fnum;
   10530           0 :         NTSTATUS status;
   10531           5 :         status = cli_openx_recv(req, &fnum);
   10532           5 :         TALLOC_FREE(req);
   10533             : 
   10534           5 :         d_printf("cli_openx_recv returned %s: %d\n",
   10535             :                  nt_errstr(status),
   10536           5 :                  NT_STATUS_IS_OK(status) ? fnum : -1);
   10537           5 : }
   10538             : 
   10539           5 : static void chain1_write_completion(struct tevent_req *req)
   10540             : {
   10541           0 :         size_t written;
   10542           0 :         NTSTATUS status;
   10543           5 :         status = cli_write_andx_recv(req, &written);
   10544           5 :         TALLOC_FREE(req);
   10545             : 
   10546           5 :         d_printf("cli_write_andx_recv returned %s: %d\n",
   10547             :                  nt_errstr(status),
   10548           5 :                  NT_STATUS_IS_OK(status) ? (int)written : -1);
   10549           5 : }
   10550             : 
   10551           5 : static void chain1_close_completion(struct tevent_req *req)
   10552             : {
   10553           0 :         NTSTATUS status;
   10554           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10555             : 
   10556           5 :         status = cli_close_recv(req);
   10557           5 :         *done = true;
   10558             : 
   10559           5 :         TALLOC_FREE(req);
   10560             : 
   10561           5 :         d_printf("cli_close returned %s\n", nt_errstr(status));
   10562           5 : }
   10563             : 
   10564           5 : static bool run_chain1(int dummy)
   10565             : {
   10566           0 :         struct cli_state *cli1;
   10567           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10568           0 :         struct tevent_req *reqs[3], *smbreqs[3];
   10569           5 :         bool done = false;
   10570           5 :         const char *str = "foobar";
   10571           5 :         const char *fname = "\\test_chain";
   10572           0 :         NTSTATUS status;
   10573             : 
   10574           5 :         printf("starting chain1 test\n");
   10575           5 :         if (!torture_open_connection(&cli1, 0)) {
   10576           0 :                 return False;
   10577             :         }
   10578             : 
   10579           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10580             : 
   10581           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10582             : 
   10583           5 :         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
   10584             :                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
   10585           5 :         if (reqs[0] == NULL) return false;
   10586           5 :         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
   10587             : 
   10588             : 
   10589           5 :         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
   10590           5 :                                         (const uint8_t *)str, 0, strlen(str)+1,
   10591             :                                         smbreqs, 1, &smbreqs[1]);
   10592           5 :         if (reqs[1] == NULL) return false;
   10593           5 :         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
   10594             : 
   10595           5 :         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
   10596           5 :         if (reqs[2] == NULL) return false;
   10597           5 :         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
   10598             : 
   10599           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10600           5 :         if (!NT_STATUS_IS_OK(status)) {
   10601           0 :                 return false;
   10602             :         }
   10603             : 
   10604          35 :         while (!done) {
   10605          30 :                 tevent_loop_once(evt);
   10606             :         }
   10607             : 
   10608           5 :         torture_close_connection(cli1);
   10609           5 :         return True;
   10610             : }
   10611             : 
   10612           5 : static void chain2_sesssetup_completion(struct tevent_req *req)
   10613             : {
   10614           0 :         NTSTATUS status;
   10615           5 :         status = cli_session_setup_guest_recv(req);
   10616           5 :         d_printf("sesssetup returned %s\n", nt_errstr(status));
   10617           5 : }
   10618             : 
   10619           5 : static void chain2_tcon_completion(struct tevent_req *req)
   10620             : {
   10621           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10622           0 :         NTSTATUS status;
   10623           5 :         status = cli_tcon_andx_recv(req);
   10624           5 :         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
   10625           5 :         *done = true;
   10626           5 : }
   10627             : 
   10628           5 : static bool run_chain2(int dummy)
   10629             : {
   10630           0 :         struct cli_state *cli1;
   10631           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10632           0 :         struct tevent_req *reqs[2], *smbreqs[2];
   10633           5 :         bool done = false;
   10634           0 :         NTSTATUS status;
   10635           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
   10636             : 
   10637           5 :         printf("starting chain2 test\n");
   10638           5 :         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
   10639             :                                       port_to_use, SMB_SIGNING_DEFAULT, flags);
   10640           5 :         if (!NT_STATUS_IS_OK(status)) {
   10641           0 :                 return False;
   10642             :         }
   10643             : 
   10644           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10645             : 
   10646           5 :         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
   10647             :                                                  &smbreqs[0]);
   10648           5 :         if (reqs[0] == NULL) return false;
   10649           5 :         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
   10650             : 
   10651           5 :         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
   10652             :                                        "?????", NULL, 0, &smbreqs[1]);
   10653           5 :         if (reqs[1] == NULL) return false;
   10654           5 :         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
   10655             : 
   10656           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10657           5 :         if (!NT_STATUS_IS_OK(status)) {
   10658           0 :                 return false;
   10659             :         }
   10660             : 
   10661          30 :         while (!done) {
   10662          25 :                 tevent_loop_once(evt);
   10663             :         }
   10664             : 
   10665           5 :         torture_close_connection(cli1);
   10666           5 :         return True;
   10667             : }
   10668             : 
   10669             : 
   10670             : struct torture_createdel_state {
   10671             :         struct tevent_context *ev;
   10672             :         struct cli_state *cli;
   10673             : };
   10674             : 
   10675             : static void torture_createdel_created(struct tevent_req *subreq);
   10676             : static void torture_createdel_closed(struct tevent_req *subreq);
   10677             : 
   10678           0 : static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
   10679             :                                                  struct tevent_context *ev,
   10680             :                                                  struct cli_state *cli,
   10681             :                                                  const char *name)
   10682             : {
   10683           0 :         struct tevent_req *req, *subreq;
   10684           0 :         struct torture_createdel_state *state;
   10685             : 
   10686           0 :         req = tevent_req_create(mem_ctx, &state,
   10687             :                                 struct torture_createdel_state);
   10688           0 :         if (req == NULL) {
   10689           0 :                 return NULL;
   10690             :         }
   10691           0 :         state->ev = ev;
   10692           0 :         state->cli = cli;
   10693             : 
   10694           0 :         subreq = cli_ntcreate_send(
   10695             :                 state, ev, cli, name, 0,
   10696             :                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
   10697             :                 FILE_ATTRIBUTE_NORMAL,
   10698             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   10699             :                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
   10700             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
   10701             : 
   10702           0 :         if (tevent_req_nomem(subreq, req)) {
   10703           0 :                 return tevent_req_post(req, ev);
   10704             :         }
   10705           0 :         tevent_req_set_callback(subreq, torture_createdel_created, req);
   10706           0 :         return req;
   10707             : }
   10708             : 
   10709           0 : static void torture_createdel_created(struct tevent_req *subreq)
   10710             : {
   10711           0 :         struct tevent_req *req = tevent_req_callback_data(
   10712             :                 subreq, struct tevent_req);
   10713           0 :         struct torture_createdel_state *state = tevent_req_data(
   10714             :                 req, struct torture_createdel_state);
   10715           0 :         NTSTATUS status;
   10716           0 :         uint16_t fnum;
   10717             : 
   10718           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
   10719           0 :         TALLOC_FREE(subreq);
   10720           0 :         if (tevent_req_nterror(req, status)) {
   10721           0 :                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
   10722             :                            nt_errstr(status)));
   10723           0 :                 return;
   10724             :         }
   10725             : 
   10726           0 :         subreq = cli_close_send(state, state->ev, state->cli, fnum, 0);
   10727           0 :         if (tevent_req_nomem(subreq, req)) {
   10728           0 :                 return;
   10729             :         }
   10730           0 :         tevent_req_set_callback(subreq, torture_createdel_closed, req);
   10731             : }
   10732             : 
   10733           0 : static void torture_createdel_closed(struct tevent_req *subreq)
   10734             : {
   10735           0 :         struct tevent_req *req = tevent_req_callback_data(
   10736             :                 subreq, struct tevent_req);
   10737           0 :         NTSTATUS status;
   10738             : 
   10739           0 :         status = cli_close_recv(subreq);
   10740           0 :         if (tevent_req_nterror(req, status)) {
   10741           0 :                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
   10742           0 :                 return;
   10743             :         }
   10744           0 :         tevent_req_done(req);
   10745             : }
   10746             : 
   10747           0 : static NTSTATUS torture_createdel_recv(struct tevent_req *req)
   10748             : {
   10749           0 :         return tevent_req_simple_recv_ntstatus(req);
   10750             : }
   10751             : 
   10752             : struct torture_createdels_state {
   10753             :         struct tevent_context *ev;
   10754             :         struct cli_state *cli;
   10755             :         const char *base_name;
   10756             :         int sent;
   10757             :         int received;
   10758             :         int num_files;
   10759             :         struct tevent_req **reqs;
   10760             : };
   10761             : 
   10762             : static void torture_createdels_done(struct tevent_req *subreq);
   10763             : 
   10764           0 : static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
   10765             :                                                   struct tevent_context *ev,
   10766             :                                                   struct cli_state *cli,
   10767             :                                                   const char *base_name,
   10768             :                                                   int num_parallel,
   10769             :                                                   int num_files)
   10770             : {
   10771           0 :         struct tevent_req *req;
   10772           0 :         struct torture_createdels_state *state;
   10773           0 :         int i;
   10774             : 
   10775           0 :         req = tevent_req_create(mem_ctx, &state,
   10776             :                                 struct torture_createdels_state);
   10777           0 :         if (req == NULL) {
   10778           0 :                 return NULL;
   10779             :         }
   10780           0 :         state->ev = ev;
   10781           0 :         state->cli = cli;
   10782           0 :         state->base_name = talloc_strdup(state, base_name);
   10783           0 :         if (tevent_req_nomem(state->base_name, req)) {
   10784           0 :                 return tevent_req_post(req, ev);
   10785             :         }
   10786           0 :         state->num_files = MAX(num_parallel, num_files);
   10787           0 :         state->sent = 0;
   10788           0 :         state->received = 0;
   10789             : 
   10790           0 :         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
   10791           0 :         if (tevent_req_nomem(state->reqs, req)) {
   10792           0 :                 return tevent_req_post(req, ev);
   10793             :         }
   10794             : 
   10795           0 :         for (i=0; i<num_parallel; i++) {
   10796           0 :                 char *name;
   10797             : 
   10798           0 :                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10799           0 :                                        state->sent);
   10800           0 :                 if (tevent_req_nomem(name, req)) {
   10801           0 :                         return tevent_req_post(req, ev);
   10802             :                 }
   10803           0 :                 state->reqs[i] = torture_createdel_send(
   10804           0 :                         state->reqs, state->ev, state->cli, name);
   10805           0 :                 if (tevent_req_nomem(state->reqs[i], req)) {
   10806           0 :                         return tevent_req_post(req, ev);
   10807             :                 }
   10808           0 :                 name = talloc_move(state->reqs[i], &name);
   10809           0 :                 tevent_req_set_callback(state->reqs[i],
   10810             :                                         torture_createdels_done, req);
   10811           0 :                 state->sent += 1;
   10812             :         }
   10813           0 :         return req;
   10814             : }
   10815             : 
   10816           0 : static void torture_createdels_done(struct tevent_req *subreq)
   10817             : {
   10818           0 :         struct tevent_req *req = tevent_req_callback_data(
   10819             :                 subreq, struct tevent_req);
   10820           0 :         struct torture_createdels_state *state = tevent_req_data(
   10821             :                 req, struct torture_createdels_state);
   10822           0 :         size_t i, num_parallel = talloc_array_length(state->reqs);
   10823           0 :         NTSTATUS status;
   10824           0 :         char *name;
   10825             : 
   10826           0 :         status = torture_createdel_recv(subreq);
   10827           0 :         if (!NT_STATUS_IS_OK(status)){
   10828           0 :                 DEBUG(10, ("torture_createdel_recv returned %s\n",
   10829             :                            nt_errstr(status)));
   10830           0 :                 TALLOC_FREE(subreq);
   10831           0 :                 tevent_req_nterror(req, status);
   10832           0 :                 return;
   10833             :         }
   10834             : 
   10835           0 :         for (i=0; i<num_parallel; i++) {
   10836           0 :                 if (subreq == state->reqs[i]) {
   10837           0 :                         break;
   10838             :                 }
   10839             :         }
   10840           0 :         if (i == num_parallel) {
   10841           0 :                 DEBUG(10, ("received something we did not send\n"));
   10842           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
   10843           0 :                 return;
   10844             :         }
   10845           0 :         TALLOC_FREE(state->reqs[i]);
   10846             : 
   10847           0 :         if (state->sent >= state->num_files) {
   10848           0 :                 tevent_req_done(req);
   10849           0 :                 return;
   10850             :         }
   10851             : 
   10852           0 :         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10853             :                                state->sent);
   10854           0 :         if (tevent_req_nomem(name, req)) {
   10855           0 :                 return;
   10856             :         }
   10857           0 :         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
   10858             :                                                 state->cli, name);
   10859           0 :         if (tevent_req_nomem(state->reqs[i], req)) {
   10860           0 :                 return;
   10861             :         }
   10862           0 :         name = talloc_move(state->reqs[i], &name);
   10863           0 :         tevent_req_set_callback(state->reqs[i],      torture_createdels_done, req);
   10864           0 :         state->sent += 1;
   10865             : }
   10866             : 
   10867           0 : static NTSTATUS torture_createdels_recv(struct tevent_req *req)
   10868             : {
   10869           0 :         return tevent_req_simple_recv_ntstatus(req);
   10870             : }
   10871             : 
   10872             : struct swallow_notify_state {
   10873             :         struct tevent_context *ev;
   10874             :         struct cli_state *cli;
   10875             :         uint16_t fnum;
   10876             :         uint32_t completion_filter;
   10877             :         bool recursive;
   10878             :         bool (*fn)(uint32_t action, const char *name, void *priv);
   10879             :         void *priv;
   10880             : };
   10881             : 
   10882             : static void swallow_notify_done(struct tevent_req *subreq);
   10883             : 
   10884           0 : static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
   10885             :                                               struct tevent_context *ev,
   10886             :                                               struct cli_state *cli,
   10887             :                                               uint16_t fnum,
   10888             :                                               uint32_t completion_filter,
   10889             :                                               bool recursive,
   10890             :                                               bool (*fn)(uint32_t action,
   10891             :                                                          const char *name,
   10892             :                                                          void *priv),
   10893             :                                               void *priv)
   10894             : {
   10895           0 :         struct tevent_req *req, *subreq;
   10896           0 :         struct swallow_notify_state *state;
   10897             : 
   10898           0 :         req = tevent_req_create(mem_ctx, &state,
   10899             :                                 struct swallow_notify_state);
   10900           0 :         if (req == NULL) {
   10901           0 :                 return NULL;
   10902             :         }
   10903           0 :         state->ev = ev;
   10904           0 :         state->cli = cli;
   10905           0 :         state->fnum = fnum;
   10906           0 :         state->completion_filter = completion_filter;
   10907           0 :         state->recursive = recursive;
   10908           0 :         state->fn = fn;
   10909           0 :         state->priv = priv;
   10910             : 
   10911           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10912           0 :                                  0xffff, state->completion_filter,
   10913           0 :                                  state->recursive);
   10914           0 :         if (tevent_req_nomem(subreq, req)) {
   10915           0 :                 return tevent_req_post(req, ev);
   10916             :         }
   10917           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10918           0 :         return req;
   10919             : }
   10920             : 
   10921           0 : static void swallow_notify_done(struct tevent_req *subreq)
   10922             : {
   10923           0 :         struct tevent_req *req = tevent_req_callback_data(
   10924             :                 subreq, struct tevent_req);
   10925           0 :         struct swallow_notify_state *state = tevent_req_data(
   10926             :                 req, struct swallow_notify_state);
   10927           0 :         NTSTATUS status;
   10928           0 :         uint32_t i, num_changes;
   10929           0 :         struct notify_change *changes;
   10930             : 
   10931           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
   10932           0 :         TALLOC_FREE(subreq);
   10933           0 :         if (!NT_STATUS_IS_OK(status)) {
   10934           0 :                 DEBUG(10, ("cli_notify_recv returned %s\n",
   10935             :                            nt_errstr(status)));
   10936           0 :                 tevent_req_nterror(req, status);
   10937           0 :                 return;
   10938             :         }
   10939             : 
   10940           0 :         for (i=0; i<num_changes; i++) {
   10941           0 :                 state->fn(changes[i].action, changes[i].name, state->priv);
   10942             :         }
   10943           0 :         TALLOC_FREE(changes);
   10944             : 
   10945           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10946             :                                  0xffff, state->completion_filter,
   10947           0 :                                  state->recursive);
   10948           0 :         if (tevent_req_nomem(subreq, req)) {
   10949           0 :                 return;
   10950             :         }
   10951           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10952             : }
   10953             : 
   10954           0 : static bool print_notifies(uint32_t action, const char *name, void *priv)
   10955             : {
   10956           0 :         if (DEBUGLEVEL > 5) {
   10957           0 :                 d_printf("%d %s\n", (int)action, name);
   10958             :         }
   10959           0 :         return true;
   10960             : }
   10961             : 
   10962           0 : static void notify_bench_done(struct tevent_req *req)
   10963             : {
   10964           0 :         int *num_finished = (int *)tevent_req_callback_data_void(req);
   10965           0 :         *num_finished += 1;
   10966           0 : }
   10967             : 
   10968           0 : static bool run_notify_bench(int dummy)
   10969             : {
   10970           0 :         const char *dname = "\\notify-bench";
   10971           0 :         struct tevent_context *ev;
   10972           0 :         NTSTATUS status;
   10973           0 :         uint16_t dnum;
   10974           0 :         struct tevent_req *req1;
   10975           0 :         struct tevent_req *req2 = NULL;
   10976           0 :         int i, num_unc_names;
   10977           0 :         int num_finished = 0;
   10978             : 
   10979           0 :         printf("starting notify-bench test\n");
   10980             : 
   10981           0 :         if (use_multishare_conn) {
   10982           0 :                 char **unc_list;
   10983           0 :                 unc_list = file_lines_load(multishare_conn_fname,
   10984             :                                            &num_unc_names, 0, NULL);
   10985           0 :                 if (!unc_list || num_unc_names <= 0) {
   10986           0 :                         d_printf("Failed to load unc names list from '%s'\n",
   10987             :                                  multishare_conn_fname);
   10988           0 :                         return false;
   10989             :                 }
   10990           0 :                 TALLOC_FREE(unc_list);
   10991             :         } else {
   10992           0 :                 num_unc_names = 1;
   10993             :         }
   10994             : 
   10995           0 :         ev = samba_tevent_context_init(talloc_tos());
   10996           0 :         if (ev == NULL) {
   10997           0 :                 d_printf("tevent_context_init failed\n");
   10998           0 :                 return false;
   10999             :         }
   11000             : 
   11001           0 :         for (i=0; i<num_unc_names; i++) {
   11002           0 :                 struct cli_state *cli;
   11003           0 :                 char *base_fname;
   11004             : 
   11005           0 :                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
   11006             :                                              dname, i);
   11007           0 :                 if (base_fname == NULL) {
   11008           0 :                         return false;
   11009             :                 }
   11010             : 
   11011           0 :                 if (!torture_open_connection(&cli, i)) {
   11012           0 :                         return false;
   11013             :                 }
   11014             : 
   11015           0 :                 status = cli_ntcreate(cli, dname, 0,
   11016             :                                       MAXIMUM_ALLOWED_ACCESS,
   11017             :                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
   11018             :                                       FILE_SHARE_DELETE,
   11019             :                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
   11020             :                                       &dnum, NULL);
   11021             : 
   11022           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11023           0 :                         d_printf("Could not create %s: %s\n", dname,
   11024             :                                  nt_errstr(status));
   11025           0 :                         return false;
   11026             :                 }
   11027             : 
   11028           0 :                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
   11029             :                                            FILE_NOTIFY_CHANGE_FILE_NAME |
   11030             :                                            FILE_NOTIFY_CHANGE_DIR_NAME |
   11031             :                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
   11032             :                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
   11033             :                                            false, print_notifies, NULL);
   11034           0 :                 if (req1 == NULL) {
   11035           0 :                         d_printf("Could not create notify request\n");
   11036           0 :                         return false;
   11037             :                 }
   11038             : 
   11039           0 :                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
   11040             :                                                base_fname, 10, torture_numops);
   11041           0 :                 if (req2 == NULL) {
   11042           0 :                         d_printf("Could not create createdels request\n");
   11043           0 :                         return false;
   11044             :                 }
   11045           0 :                 TALLOC_FREE(base_fname);
   11046             : 
   11047           0 :                 tevent_req_set_callback(req2, notify_bench_done,
   11048             :                                         &num_finished);
   11049             :         }
   11050             : 
   11051           0 :         while (num_finished < num_unc_names) {
   11052           0 :                 int ret;
   11053           0 :                 ret = tevent_loop_once(ev);
   11054           0 :                 if (ret != 0) {
   11055           0 :                         d_printf("tevent_loop_once failed\n");
   11056           0 :                         return false;
   11057             :                 }
   11058             :         }
   11059             : 
   11060           0 :         if (!tevent_req_poll(req2, ev)) {
   11061           0 :                 d_printf("tevent_req_poll failed\n");
   11062             :         }
   11063             : 
   11064           0 :         status = torture_createdels_recv(req2);
   11065           0 :         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
   11066             : 
   11067           0 :         return true;
   11068             : }
   11069             : 
   11070           0 : static bool run_mangle1(int dummy)
   11071             : {
   11072           0 :         struct cli_state *cli;
   11073           0 :         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
   11074           0 :         uint16_t fnum;
   11075           0 :         fstring alt_name;
   11076           0 :         NTSTATUS status;
   11077             : 
   11078           0 :         printf("starting mangle1 test\n");
   11079           0 :         if (!torture_open_connection(&cli, 0)) {
   11080           0 :                 return False;
   11081             :         }
   11082             : 
   11083           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11084             : 
   11085           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11086             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11087             :                               0, 0, &fnum, NULL);
   11088           0 :         if (!NT_STATUS_IS_OK(status)) {
   11089           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11090           0 :                 return false;
   11091             :         }
   11092           0 :         cli_close(cli, fnum);
   11093             : 
   11094           0 :         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
   11095           0 :         if (!NT_STATUS_IS_OK(status)) {
   11096           0 :                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
   11097             :                          nt_errstr(status));
   11098           0 :                 return false;
   11099             :         }
   11100           0 :         d_printf("alt_name: %s\n", alt_name);
   11101             : 
   11102           0 :         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
   11103           0 :         if (!NT_STATUS_IS_OK(status)) {
   11104           0 :                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
   11105             :                          nt_errstr(status));
   11106           0 :                 return false;
   11107             :         }
   11108           0 :         cli_close(cli, fnum);
   11109             : 
   11110           0 :         status = cli_qpathinfo1(cli, alt_name, NULL, NULL, NULL, NULL, NULL);
   11111           0 :         if (!NT_STATUS_IS_OK(status)) {
   11112           0 :                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
   11113             :                          nt_errstr(status));
   11114           0 :                 return false;
   11115             :         }
   11116             : 
   11117           0 :         return true;
   11118             : }
   11119             : 
   11120           2 : static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
   11121             :                                                  const char *mask,
   11122             :                                                  void *state)
   11123             : {
   11124           2 :         if (f->short_name == NULL) {
   11125           2 :                 return NT_STATUS_OK;
   11126             :         }
   11127             : 
   11128           0 :         if (strlen(f->short_name) == 0) {
   11129           0 :                 return NT_STATUS_OK;
   11130             :         }
   11131             : 
   11132           0 :         printf("unexpected shortname: %s\n", f->short_name);
   11133             : 
   11134           0 :         return NT_STATUS_OBJECT_NAME_INVALID;
   11135             : }
   11136             : 
   11137           2 : static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
   11138             :                                             const char *mask,
   11139             :                                             void *state)
   11140             : {
   11141           2 :         char *name = state;
   11142             : 
   11143           2 :         printf("name: %s\n", f->name);
   11144           2 :         fstrcpy(name, f->name);
   11145           2 :         return NT_STATUS_OK;
   11146             : }
   11147             : 
   11148           2 : static bool run_mangle_illegal(int dummy)
   11149             : {
   11150           2 :         struct cli_state *cli = NULL;
   11151           2 :         struct cli_state *cli_posix = NULL;
   11152           2 :         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
   11153           2 :         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
   11154           2 :         char *mangled_path = NULL;
   11155           0 :         uint16_t fnum;
   11156           0 :         fstring name;
   11157           0 :         fstring alt_name;
   11158           0 :         NTSTATUS status;
   11159             : 
   11160           2 :         printf("starting mangle-illegal test\n");
   11161             : 
   11162           2 :         if (!torture_open_connection(&cli, 0)) {
   11163           0 :                 return False;
   11164             :         }
   11165             : 
   11166           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11167             : 
   11168           2 :         if (!torture_open_connection(&cli_posix, 0)) {
   11169           0 :                 return false;
   11170             :         }
   11171             : 
   11172           2 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   11173             : 
   11174           2 :         status = torture_setup_unix_extensions(cli_posix);
   11175           2 :         if (!NT_STATUS_IS_OK(status)) {
   11176           0 :                 return false;
   11177             :         }
   11178             : 
   11179           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11180           2 :         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
   11181           2 :         if (!NT_STATUS_IS_OK(status)) {
   11182           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   11183           0 :                 return False;
   11184             :         }
   11185             : 
   11186             :         /*
   11187             :          * Create a file with illegal NTFS characters and test that we
   11188             :          * get a usable mangled name
   11189             :          */
   11190             : 
   11191           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11192           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11193             : 
   11194           2 :         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
   11195             :                                 0600, &fnum);
   11196           2 :         if (!NT_STATUS_IS_OK(status)) {
   11197           0 :                 printf("POSIX create of %s failed (%s)\n",
   11198             :                        illegal_fname, nt_errstr(status));
   11199           0 :                 return false;
   11200             :         }
   11201             : 
   11202           2 :         status = cli_close(cli_posix, fnum);
   11203           2 :         if (!NT_STATUS_IS_OK(status)) {
   11204           0 :                 printf("close failed (%s)\n", nt_errstr(status));
   11205           0 :                 return false;
   11206             :         }
   11207             : 
   11208           2 :         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
   11209           2 :         if (!NT_STATUS_IS_OK(status)) {
   11210           0 :                 d_printf("cli_list failed: %s\n", nt_errstr(status));
   11211           0 :                 return false;
   11212             :         }
   11213             : 
   11214           2 :         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
   11215           2 :         if (mangled_path == NULL) {
   11216           0 :                 return false;
   11217             :         }
   11218             : 
   11219           2 :         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
   11220           2 :         if (!NT_STATUS_IS_OK(status)) {
   11221           0 :                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
   11222           0 :                 TALLOC_FREE(mangled_path);
   11223           0 :                 return false;
   11224             :         }
   11225           2 :         TALLOC_FREE(mangled_path);
   11226           2 :         cli_close(cli, fnum);
   11227             : 
   11228           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11229           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11230             : 
   11231             :         /*
   11232             :          * Create a file with a long name and check that we got *no* short name.
   11233             :          */
   11234             : 
   11235           2 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11236             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11237             :                               0, 0, &fnum, NULL);
   11238           2 :         if (!NT_STATUS_IS_OK(status)) {
   11239           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11240           0 :                 return false;
   11241             :         }
   11242           2 :         cli_close(cli, fnum);
   11243             : 
   11244           2 :         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
   11245           2 :         if (!NT_STATUS_IS_OK(status)) {
   11246           0 :                 d_printf("cli_list failed\n");
   11247           0 :                 return false;
   11248             :         }
   11249             : 
   11250           2 :         cli_unlink(cli, fname, 0);
   11251           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11252             : 
   11253           2 :         if (!torture_close_connection(cli_posix)) {
   11254           0 :                 return false;
   11255             :         }
   11256             : 
   11257           2 :         if (!torture_close_connection(cli)) {
   11258           0 :                 return false;
   11259             :         }
   11260             : 
   11261           2 :         return true;
   11262             : }
   11263             : 
   11264           0 : static size_t null_source(uint8_t *buf, size_t n, void *priv)
   11265             : {
   11266           0 :         size_t *to_pull = (size_t *)priv;
   11267           0 :         size_t thistime = *to_pull;
   11268             : 
   11269           0 :         thistime = MIN(thistime, n);
   11270           0 :         if (thistime == 0) {
   11271           0 :                 return 0;
   11272             :         }
   11273             : 
   11274           0 :         memset(buf, 0, thistime);
   11275           0 :         *to_pull -= thistime;
   11276           0 :         return thistime;
   11277             : }
   11278             : 
   11279           0 : static bool run_windows_write(int dummy)
   11280             : {
   11281           0 :         struct cli_state *cli1;
   11282           0 :         uint16_t fnum;
   11283           0 :         int i;
   11284           0 :         bool ret = false;
   11285           0 :         const char *fname = "\\writetest.txt";
   11286           0 :         struct timeval start_time;
   11287           0 :         double seconds;
   11288           0 :         double kbytes;
   11289           0 :         NTSTATUS status;
   11290             : 
   11291           0 :         printf("starting windows_write test\n");
   11292           0 :         if (!torture_open_connection(&cli1, 0)) {
   11293           0 :                 return False;
   11294             :         }
   11295             : 
   11296           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   11297           0 :         if (!NT_STATUS_IS_OK(status)) {
   11298           0 :                 printf("open failed (%s)\n", nt_errstr(status));
   11299           0 :                 return False;
   11300             :         }
   11301             : 
   11302           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   11303             : 
   11304           0 :         start_time = timeval_current();
   11305             : 
   11306           0 :         for (i=0; i<torture_numops; i++) {
   11307           0 :                 uint8_t c = 0;
   11308           0 :                 off_t start = i * torture_blocksize;
   11309           0 :                 size_t to_pull = torture_blocksize - 1;
   11310             : 
   11311           0 :                 status = cli_writeall(cli1, fnum, 0, &c,
   11312           0 :                                       start + torture_blocksize - 1, 1, NULL);
   11313           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11314           0 :                         printf("cli_write failed: %s\n", nt_errstr(status));
   11315           0 :                         goto fail;
   11316             :                 }
   11317             : 
   11318           0 :                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
   11319             :                                   null_source, &to_pull);
   11320           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11321           0 :                         printf("cli_push returned: %s\n", nt_errstr(status));
   11322           0 :                         goto fail;
   11323             :                 }
   11324             :         }
   11325             : 
   11326           0 :         seconds = timeval_elapsed(&start_time);
   11327           0 :         kbytes = (double)torture_blocksize * torture_numops;
   11328           0 :         kbytes /= 1024;
   11329             : 
   11330           0 :         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
   11331           0 :                (double)seconds, (int)(kbytes/seconds));
   11332             : 
   11333           0 :         ret = true;
   11334           0 :  fail:
   11335           0 :         cli_close(cli1, fnum);
   11336           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11337           0 :         torture_close_connection(cli1);
   11338           0 :         return ret;
   11339             : }
   11340             : 
   11341          64 : static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
   11342             : {
   11343          64 :         size_t max_pdu = 0x1FFFF;
   11344             : 
   11345          64 :         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
   11346          32 :                 max_pdu = 0xFFFFFF;
   11347             :         }
   11348             : 
   11349          64 :         if (smb1cli_conn_signing_is_active(cli->conn)) {
   11350          32 :                 max_pdu = 0x1FFFF;
   11351             :         }
   11352             : 
   11353          64 :         if (smb1cli_conn_encryption_on(cli->conn)) {
   11354          16 :                 max_pdu = CLI_BUFFER_SIZE;
   11355             :         }
   11356             : 
   11357          64 :         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
   11358           8 :                 len_requested &= 0xFFFF;
   11359             :         }
   11360             : 
   11361          64 :         return MIN(len_requested,
   11362             :                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
   11363             : }
   11364             : 
   11365          64 : static bool check_read_call(struct cli_state *cli,
   11366             :                             uint16_t fnum,
   11367             :                             uint8_t *buf,
   11368             :                             size_t len_requested)
   11369             : {
   11370           0 :         NTSTATUS status;
   11371          64 :         struct tevent_req *subreq = NULL;
   11372          64 :         ssize_t len_read = 0;
   11373          64 :         size_t len_expected = 0;
   11374          64 :         struct tevent_context *ev = NULL;
   11375             : 
   11376          64 :         ev = samba_tevent_context_init(talloc_tos());
   11377          64 :         if (ev == NULL) {
   11378           0 :                 return false;
   11379             :         }
   11380             : 
   11381          64 :         subreq = cli_read_andx_send(talloc_tos(),
   11382             :                                     ev,
   11383             :                                     cli,
   11384             :                                     fnum,
   11385             :                                     0,
   11386             :                                     len_requested);
   11387             : 
   11388          64 :         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
   11389           0 :                 return false;
   11390             :         }
   11391             : 
   11392          64 :         status = cli_read_andx_recv(subreq, &len_read, &buf);
   11393          64 :         if (!NT_STATUS_IS_OK(status)) {
   11394           0 :                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
   11395           0 :                 return false;
   11396             :         }
   11397             : 
   11398          64 :         TALLOC_FREE(subreq);
   11399          64 :         TALLOC_FREE(ev);
   11400             : 
   11401          64 :         len_expected = calc_expected_return(cli, len_requested);
   11402             : 
   11403          64 :         if (len_expected > 0x10000 && len_read == 0x10000) {
   11404             :                 /* Windows servers only return a max of 0x10000,
   11405             :                    doesn't matter if you set CAP_LARGE_READX in
   11406             :                    the client sessionsetupX call or not. */
   11407          12 :                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
   11408             :                         (unsigned int)len_requested);
   11409          52 :         } else if (len_read != len_expected) {
   11410           0 :                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
   11411             :                         (unsigned int)len_requested,
   11412             :                         (unsigned int)len_read,
   11413             :                         (unsigned int)len_expected);
   11414           0 :                 return false;
   11415             :         } else {
   11416          52 :                 d_printf("Correct read reply.\n");
   11417             :         }
   11418             : 
   11419          64 :         return true;
   11420             : }
   11421             : 
   11422             : /* Test large readX variants. */
   11423           8 : static bool large_readx_tests(struct cli_state *cli,
   11424             :                                 uint16_t fnum,
   11425             :                                 uint8_t *buf)
   11426             : {
   11427             :         /* A read of 0xFFFF0001 should *always* return 1 byte. */
   11428           8 :         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
   11429           0 :                 return false;
   11430             :         }
   11431             :         /* A read of 0x10000 should return 0x10000 bytes. */
   11432           8 :         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
   11433           0 :                 return false;
   11434             :         }
   11435             :         /* A read of 0x10000 should return 0x10001 bytes. */
   11436           8 :         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
   11437           0 :                 return false;
   11438             :         }
   11439             :         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
   11440             :            the requested number of bytes. */
   11441           8 :         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
   11442           0 :                 return false;
   11443             :         }
   11444             :         /* A read of 1MB should return 1MB bytes (on Samba). */
   11445           8 :         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
   11446           0 :                 return false;
   11447             :         }
   11448             : 
   11449           8 :         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
   11450           0 :                 return false;
   11451             :         }
   11452           8 :         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
   11453           0 :                 return false;
   11454             :         }
   11455           8 :         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
   11456           0 :                 return false;
   11457             :         }
   11458           8 :         return true;
   11459             : }
   11460             : 
   11461           5 : static bool run_large_readx(int dummy)
   11462             : {
   11463           5 :         uint8_t *buf = NULL;
   11464           5 :         struct cli_state *cli1 = NULL;
   11465           5 :         struct cli_state *cli2 = NULL;
   11466           5 :         bool correct = false;
   11467           5 :         const char *fname = "\\large_readx.dat";
   11468           0 :         NTSTATUS status;
   11469           5 :         uint16_t fnum1 = UINT16_MAX;
   11470           5 :         uint32_t normal_caps = 0;
   11471           5 :         size_t file_size = 20*1024*1024;
   11472           5 :         TALLOC_CTX *frame = talloc_stackframe();
   11473           0 :         size_t i;
   11474           0 :         struct {
   11475             :                 const char *name;
   11476             :                 enum smb_signing_setting signing_setting;
   11477             :                 enum protocol_types protocol;
   11478           5 :         } runs[] = {
   11479             :                 {
   11480             :                         .name = "NT1",
   11481             :                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
   11482             :                         .protocol = PROTOCOL_NT1,
   11483             :                 },{
   11484             :                         .name = "NT1 - SIGNING_REQUIRED",
   11485             :                         .signing_setting = SMB_SIGNING_REQUIRED,
   11486             :                         .protocol = PROTOCOL_NT1,
   11487             :                 },
   11488             :         };
   11489             : 
   11490           5 :         printf("starting large_readx test\n");
   11491             : 
   11492           5 :         if (!torture_open_connection(&cli1, 0)) {
   11493           0 :                 goto out;
   11494             :         }
   11495             : 
   11496           5 :         normal_caps = smb1cli_conn_capabilities(cli1->conn);
   11497             : 
   11498           5 :         if (!(normal_caps & CAP_LARGE_READX)) {
   11499           0 :                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11500             :                         (unsigned int)normal_caps);
   11501           0 :                 goto out;
   11502             :         }
   11503             : 
   11504             :         /* Create a file of size 4MB. */
   11505           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
   11506             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11507             :                         0, 0, &fnum1, NULL);
   11508             : 
   11509           5 :         if (!NT_STATUS_IS_OK(status)) {
   11510           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11511           0 :                 goto out;
   11512             :         }
   11513             : 
   11514             :         /* Write file_size bytes. */
   11515           5 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11516           5 :         if (buf == NULL) {
   11517           0 :                 goto out;
   11518             :         }
   11519             : 
   11520           5 :         status = cli_writeall(cli1,
   11521             :                               fnum1,
   11522             :                               0,
   11523             :                               buf,
   11524             :                               0,
   11525             :                               file_size,
   11526             :                               NULL);
   11527           5 :         if (!NT_STATUS_IS_OK(status)) {
   11528           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11529           0 :                 goto out;
   11530             :         }
   11531             : 
   11532           5 :         status = cli_close(cli1, fnum1);
   11533           5 :         if (!NT_STATUS_IS_OK(status)) {
   11534           0 :                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11535           0 :                 goto out;
   11536             :         }
   11537             : 
   11538           5 :         fnum1 = UINT16_MAX;
   11539             : 
   11540          15 :         for (i=0; i < ARRAY_SIZE(runs); i++) {
   11541          10 :                 enum smb_signing_setting saved_signing_setting = signing_state;
   11542          10 :                 uint16_t fnum2 = -1;
   11543             : 
   11544          10 :                 if (do_encrypt &&
   11545           4 :                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
   11546             :                 {
   11547           2 :                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
   11548           2 :                         continue;
   11549             :                 }
   11550             : 
   11551           8 :                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
   11552             : 
   11553           8 :                 signing_state = runs[i].signing_setting;
   11554           8 :                 cli2 = open_nbt_connection();
   11555           8 :                 signing_state = saved_signing_setting;
   11556           8 :                 if (cli2 == NULL) {
   11557           0 :                         goto out;
   11558             :                 }
   11559             : 
   11560           8 :                 status = smbXcli_negprot(cli2->conn,
   11561           8 :                                          cli2->timeout,
   11562             :                                          runs[i].protocol,
   11563             :                                          runs[i].protocol,
   11564             :                                          NULL,
   11565             :                                          NULL,
   11566             :                                          NULL);
   11567           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11568           0 :                         goto out;
   11569             :                 }
   11570             : 
   11571           8 :                 status = cli_session_setup_creds(cli2, torture_creds);
   11572           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11573           0 :                         goto out;
   11574             :                 }
   11575             : 
   11576           8 :                 status = cli_tree_connect(cli2,
   11577             :                                         share,
   11578             :                                         "?????",
   11579             :                                         password);
   11580           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11581           0 :                         goto out;
   11582             :                 }
   11583             : 
   11584           8 :                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
   11585             : 
   11586           8 :                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
   11587             : 
   11588           8 :                 if (!(normal_caps & CAP_LARGE_READX)) {
   11589           0 :                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11590             :                                 (unsigned int)normal_caps);
   11591           0 :                         goto out;
   11592             :                 }
   11593             : 
   11594           8 :                 if (do_encrypt) {
   11595           2 :                         if (force_cli_encryption(cli2, share) == false) {
   11596           0 :                                 goto out;
   11597             :                         }
   11598           6 :                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
   11599           0 :                         uint16_t major, minor;
   11600           0 :                         uint32_t caplow, caphigh;
   11601             : 
   11602           4 :                         status = cli_unix_extensions_version(cli2,
   11603             :                                                              &major, &minor,
   11604             :                                                              &caplow, &caphigh);
   11605           4 :                         if (!NT_STATUS_IS_OK(status)) {
   11606           0 :                                 goto out;
   11607             :                         }
   11608             :                 }
   11609             : 
   11610           8 :                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
   11611             :                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
   11612             :                                 0, 0, &fnum2, NULL);
   11613           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11614           0 :                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
   11615           0 :                         goto out;
   11616             :                 }
   11617             : 
   11618             :                 /* All reads must return less than file_size bytes. */
   11619           8 :                 if (!large_readx_tests(cli2, fnum2, buf)) {
   11620           0 :                         goto out;
   11621             :                 }
   11622             : 
   11623           8 :                 status = cli_close(cli2, fnum2);
   11624           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11625           0 :                         d_printf("cli_close failed: %s\n", nt_errstr(status));
   11626           0 :                         goto out;
   11627             :                 }
   11628           8 :                 fnum2 = -1;
   11629             : 
   11630           8 :                 if (!torture_close_connection(cli2)) {
   11631           0 :                         goto out;
   11632             :                 }
   11633           8 :                 cli2 = NULL;
   11634             :         }
   11635             : 
   11636           5 :         correct = true;
   11637           5 :         printf("Success on large_readx test\n");
   11638             : 
   11639           5 :   out:
   11640             : 
   11641           5 :         if (cli2) {
   11642           0 :                 if (!torture_close_connection(cli2)) {
   11643           0 :                         correct = false;
   11644             :                 }
   11645             :         }
   11646             : 
   11647           5 :         if (cli1) {
   11648           5 :                 if (fnum1 != UINT16_MAX) {
   11649           0 :                         status = cli_close(cli1, fnum1);
   11650           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11651           0 :                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11652             :                         }
   11653           0 :                         fnum1 = UINT16_MAX;
   11654             :                 }
   11655             : 
   11656           5 :                 status = cli_unlink(cli1, fname,
   11657             :                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11658           5 :                 if (!NT_STATUS_IS_OK(status)) {
   11659           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
   11660             :                 }
   11661             : 
   11662           5 :                 if (!torture_close_connection(cli1)) {
   11663           0 :                         correct = false;
   11664             :                 }
   11665             :         }
   11666             : 
   11667           5 :         TALLOC_FREE(frame);
   11668             : 
   11669           5 :         printf("finished large_readx test\n");
   11670           5 :         return correct;
   11671             : }
   11672             : 
   11673          24 : static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
   11674             :                                   const char *mask,
   11675             :                                   void *private_data)
   11676             : {
   11677          24 :         uint32_t *p_attr = (uint32_t *)private_data;
   11678             : 
   11679          24 :         if (strequal(finfo->name, test_filename)) {
   11680           4 :                 *p_attr = finfo->attr;
   11681             :         }
   11682             : 
   11683          24 :         return NT_STATUS_OK;
   11684             : }
   11685             : 
   11686           4 : static bool run_msdfs_attribute(int dummy)
   11687             : {
   11688           0 :         static struct cli_state *cli;
   11689           4 :         bool correct = false;
   11690           4 :         uint32_t attr = 0;
   11691           0 :         NTSTATUS status;
   11692             : 
   11693           4 :         printf("Starting MSDFS-ATTRIBUTE test\n");
   11694             : 
   11695           4 :         if (test_filename == NULL || test_filename[0] == '\0') {
   11696           0 :                 printf("MSDFS-ATTRIBUTE test "
   11697             :                         "needs -f filename-of-msdfs-link\n");
   11698           0 :                 return false;
   11699             :         }
   11700             : 
   11701             :         /*
   11702             :          * NB. We use torture_open_connection_flags() not
   11703             :          * torture_open_connection() as the latter forces
   11704             :          * SMB1.
   11705             :          */
   11706           4 :         if (!torture_open_connection_flags(&cli, 0, 0)) {
   11707           0 :                 return false;
   11708             :         }
   11709             : 
   11710           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11711             : 
   11712           4 :         status = cli_list(cli,
   11713             :                         "*",
   11714             :                         FILE_ATTRIBUTE_DIRECTORY,
   11715             :                         msdfs_attribute_list_fn,
   11716             :                         &attr);
   11717             : 
   11718           4 :         if (!NT_STATUS_IS_OK(status)) {
   11719           0 :                 printf("cli_list failed with %s\n",
   11720             :                         nt_errstr(status));
   11721           0 :                 goto out;
   11722             :         }
   11723           4 :         if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
   11724           0 :                 printf("file %s should have "
   11725             :                         "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
   11726             :                         test_filename,
   11727             :                         (unsigned int)attr);
   11728           0 :                 goto out;
   11729             :         }
   11730             : 
   11731           4 :         if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
   11732           0 :                 printf("file %s should have "
   11733             :                         "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
   11734             :                         test_filename,
   11735             :                         (unsigned int)attr);
   11736           0 :                 goto out;
   11737             :         }
   11738             : 
   11739           4 :         correct = true;
   11740             : 
   11741           4 :   out:
   11742             : 
   11743           4 :         torture_close_connection(cli);
   11744           4 :         return correct;
   11745             : }
   11746             : 
   11747           0 : static bool run_cli_echo(int dummy)
   11748             : {
   11749           0 :         struct cli_state *cli;
   11750           0 :         NTSTATUS status;
   11751             : 
   11752           0 :         printf("starting cli_echo test\n");
   11753           0 :         if (!torture_open_connection(&cli, 0)) {
   11754           0 :                 return false;
   11755             :         }
   11756           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11757             : 
   11758           0 :         status = cli_echo(cli, 5, data_blob_const("hello", 5));
   11759             : 
   11760           0 :         d_printf("cli_echo returned %s\n", nt_errstr(status));
   11761             : 
   11762           0 :         torture_close_connection(cli);
   11763           0 :         return NT_STATUS_IS_OK(status);
   11764             : }
   11765             : 
   11766          14 : static int splice_status(off_t written, void *priv)
   11767             : {
   11768          14 :         return true;
   11769             : }
   11770             : 
   11771           7 : static bool run_cli_splice(int dummy)
   11772             : {
   11773           7 :         uint8_t *buf = NULL;
   11774           7 :         struct cli_state *cli1 = NULL;
   11775           7 :         bool correct = false;
   11776           7 :         const char *fname_src = "\\splice_src.dat";
   11777           7 :         const char *fname_dst = "\\splice_dst.dat";
   11778           0 :         NTSTATUS status;
   11779           7 :         uint16_t fnum1 = UINT16_MAX;
   11780           7 :         uint16_t fnum2 = UINT16_MAX;
   11781           7 :         size_t file_size = 2*1024*1024;
   11782           7 :         size_t splice_size = 1*1024*1024 + 713;
   11783           0 :         uint8_t digest1[16], digest2[16];
   11784           7 :         off_t written = 0;
   11785           7 :         size_t nread = 0;
   11786           7 :         TALLOC_CTX *frame = talloc_stackframe();
   11787             : 
   11788           7 :         printf("starting cli_splice test\n");
   11789             : 
   11790           7 :         if (!torture_open_connection(&cli1, 0)) {
   11791           0 :                 goto out;
   11792             :         }
   11793             : 
   11794           7 :         cli_unlink(cli1, fname_src,
   11795             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11796           7 :         cli_unlink(cli1, fname_dst,
   11797             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11798             : 
   11799             :         /* Create a file */
   11800           7 :         status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
   11801             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11802             :                         0, 0, &fnum1, NULL);
   11803             : 
   11804           7 :         if (!NT_STATUS_IS_OK(status)) {
   11805           0 :                 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
   11806           0 :                 goto out;
   11807             :         }
   11808             : 
   11809             :         /* Write file_size bytes - must be bigger than splice_size. */
   11810           7 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11811           7 :         if (buf == NULL) {
   11812           0 :                 d_printf("talloc_fail\n");
   11813           0 :                 goto out;
   11814             :         }
   11815             : 
   11816             :         /* Fill it with random numbers. */
   11817           7 :         generate_random_buffer(buf, file_size);
   11818             : 
   11819             :         /* MD5 the first 1MB + 713 bytes. */
   11820           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11821             :                          buf,
   11822             :                          splice_size,
   11823             :                          digest1);
   11824             : 
   11825           7 :         status = cli_writeall(cli1,
   11826             :                               fnum1,
   11827             :                               0,
   11828             :                               buf,
   11829             :                               0,
   11830             :                               file_size,
   11831             :                               NULL);
   11832           7 :         if (!NT_STATUS_IS_OK(status)) {
   11833           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11834           0 :                 goto out;
   11835             :         }
   11836             : 
   11837           7 :         status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
   11838             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11839             :                         0, 0, &fnum2, NULL);
   11840             : 
   11841           7 :         if (!NT_STATUS_IS_OK(status)) {
   11842           0 :                 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
   11843           0 :                 goto out;
   11844             :         }
   11845             : 
   11846             :         /* Now splice 1MB + 713 bytes. */
   11847           7 :         status = cli_splice(cli1,
   11848             :                                 cli1,
   11849             :                                 fnum1,
   11850             :                                 fnum2,
   11851             :                                 splice_size,
   11852             :                                 0,
   11853             :                                 0,
   11854             :                                 &written,
   11855             :                                 splice_status,
   11856             :                                 NULL);
   11857             : 
   11858           7 :         if (!NT_STATUS_IS_OK(status)) {
   11859           0 :                 d_printf("cli_splice failed: %s\n", nt_errstr(status));
   11860           0 :                 goto out;
   11861             :         }
   11862             : 
   11863             :         /* Clear the old buffer. */
   11864           7 :         memset(buf, '\0', file_size);
   11865             : 
   11866             :         /* Read the new file. */
   11867           7 :         status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
   11868           7 :         if (!NT_STATUS_IS_OK(status)) {
   11869           0 :                 d_printf("cli_read failed: %s\n", nt_errstr(status));
   11870           0 :                 goto out;
   11871             :         }
   11872           7 :         if (nread != splice_size) {
   11873           0 :                 d_printf("bad read of 0x%x, should be 0x%x\n",
   11874             :                         (unsigned int)nread,
   11875             :                         (unsigned int)splice_size);
   11876           0 :                 goto out;
   11877             :         }
   11878             : 
   11879             :         /* MD5 the first 1MB + 713 bytes. */
   11880           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11881             :                          buf,
   11882             :                          splice_size,
   11883             :                          digest2);
   11884             : 
   11885             :         /* Must be the same. */
   11886           7 :         if (memcmp(digest1, digest2, 16) != 0) {
   11887           0 :                 d_printf("bad MD5 compare\n");
   11888           0 :                 goto out;
   11889             :         }
   11890             : 
   11891           7 :         correct = true;
   11892           7 :         printf("Success on cli_splice test\n");
   11893             : 
   11894           7 :   out:
   11895             : 
   11896           7 :         if (cli1) {
   11897           7 :                 if (fnum1 != UINT16_MAX) {
   11898           7 :                         cli_close(cli1, fnum1);
   11899             :                 }
   11900           7 :                 if (fnum2 != UINT16_MAX) {
   11901           7 :                         cli_close(cli1, fnum2);
   11902             :                 }
   11903             : 
   11904           7 :                 cli_unlink(cli1, fname_src,
   11905             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11906           7 :                 cli_unlink(cli1, fname_dst,
   11907             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11908             : 
   11909           7 :                 if (!torture_close_connection(cli1)) {
   11910           0 :                         correct = false;
   11911             :                 }
   11912             :         }
   11913             : 
   11914           7 :         TALLOC_FREE(frame);
   11915           7 :         return correct;
   11916             : }
   11917             : 
   11918           4 : static bool run_uid_regression_test(int dummy)
   11919             : {
   11920           0 :         static struct cli_state *cli;
   11921           0 :         int16_t old_vuid;
   11922           0 :         int32_t old_cnum;
   11923           4 :         bool correct = True;
   11924           4 :         struct smbXcli_tcon *tcon_copy = NULL;
   11925           0 :         NTSTATUS status;
   11926             : 
   11927           4 :         printf("starting uid regression test\n");
   11928             : 
   11929           4 :         if (!torture_open_connection(&cli, 0)) {
   11930           0 :                 return False;
   11931             :         }
   11932             : 
   11933           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11934             : 
   11935             :         /* Ok - now save then logoff our current user. */
   11936           4 :         old_vuid = cli_state_get_uid(cli);
   11937             : 
   11938           4 :         status = cli_ulogoff(cli);
   11939           4 :         if (!NT_STATUS_IS_OK(status)) {
   11940           0 :                 d_printf("(%s) cli_ulogoff failed: %s\n",
   11941             :                          __location__, nt_errstr(status));
   11942           0 :                 correct = false;
   11943           0 :                 goto out;
   11944             :         }
   11945             : 
   11946           4 :         cli_state_set_uid(cli, old_vuid);
   11947             : 
   11948             :         /* Try an operation. */
   11949           4 :         status = cli_mkdir(cli, "\\uid_reg_test");
   11950           4 :         if (NT_STATUS_IS_OK(status)) {
   11951           0 :                 d_printf("(%s) cli_mkdir succeeded\n",
   11952             :                          __location__);
   11953           0 :                 correct = false;
   11954           0 :                 goto out;
   11955             :         } else {
   11956             :                 /* Should be bad uid. */
   11957           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
   11958           4 :                                  NT_STATUS_USER_SESSION_DELETED)) {
   11959           0 :                         correct = false;
   11960           0 :                         goto out;
   11961             :                 }
   11962             :         }
   11963             : 
   11964           4 :         old_cnum = cli_state_get_tid(cli);
   11965             :         /*
   11966             :          * This is an SMB1-only test.
   11967             :          * Copy the tcon, not "save/restore".
   11968             :          *
   11969             :          * In SMB1 the cli_tdis() below frees
   11970             :          * cli->smb1.tcon so we need a copy
   11971             :          * of the struct to put back for the
   11972             :          * second tdis call with invalid vuid.
   11973             :          *
   11974             :          * This is a test-only hack. Real client code
   11975             :          * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
   11976             :          */
   11977           4 :         tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
   11978           4 :         if (tcon_copy == NULL) {
   11979           0 :                 correct = false;
   11980           0 :                 goto out;
   11981             :         }
   11982             : 
   11983             :         /* Now try a SMBtdis with the invalid vuid set to zero. */
   11984           4 :         cli_state_set_uid(cli, 0);
   11985             : 
   11986             :         /* This should succeed. */
   11987           4 :         status = cli_tdis(cli);
   11988             : 
   11989           4 :         if (NT_STATUS_IS_OK(status)) {
   11990           4 :                 d_printf("First tdis with invalid vuid should succeed.\n");
   11991             :         } else {
   11992           0 :                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
   11993           0 :                 correct = false;
   11994           0 :                 cli->smb1.tcon = tcon_copy;
   11995           0 :                 goto out;
   11996             :         }
   11997             : 
   11998           4 :         cli->smb1.tcon = tcon_copy;
   11999           4 :         cli_state_set_uid(cli, old_vuid);
   12000           4 :         cli_state_set_tid(cli, old_cnum);
   12001             : 
   12002             :         /* This should fail. */
   12003           4 :         status = cli_tdis(cli);
   12004           4 :         if (NT_STATUS_IS_OK(status)) {
   12005           0 :                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
   12006           0 :                 correct = false;
   12007           0 :                 goto out;
   12008             :         } else {
   12009             :                 /* Should be bad tid. */
   12010           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
   12011           4 :                                 NT_STATUS_NETWORK_NAME_DELETED)) {
   12012           0 :                         correct = false;
   12013           0 :                         goto out;
   12014             :                 }
   12015             :         }
   12016             : 
   12017           4 :         cli_rmdir(cli, "\\uid_reg_test");
   12018             : 
   12019           4 :   out:
   12020             : 
   12021           4 :         cli_shutdown(cli);
   12022           4 :         return correct;
   12023             : }
   12024             : 
   12025             : 
   12026             : static const char *illegal_chars = "*\\/?<>|\":";
   12027             : static char force_shortname_chars[] = " +,.[];=\177";
   12028             : 
   12029           8 : static NTSTATUS shortname_del_fn(struct file_info *finfo,
   12030             :                              const char *mask, void *state)
   12031             : {
   12032           8 :         struct cli_state *pcli = (struct cli_state *)state;
   12033           0 :         fstring fname;
   12034           8 :         NTSTATUS status = NT_STATUS_OK;
   12035             : 
   12036           8 :         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
   12037             : 
   12038           8 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
   12039           8 :                 return NT_STATUS_OK;
   12040             : 
   12041           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
   12042           0 :                 status = cli_rmdir(pcli, fname);
   12043           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12044           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
   12045             :                 }
   12046             :         } else {
   12047           0 :                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12048           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12049           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
   12050             :                 }
   12051             :         }
   12052           0 :         return status;
   12053             : }
   12054             : 
   12055             : struct sn_state {
   12056             :         int matched;
   12057             :         int i;
   12058             :         bool val;
   12059             : };
   12060             : 
   12061         348 : static NTSTATUS shortname_list_fn(struct file_info *finfo,
   12062             :                               const char *name, void *state)
   12063             : {
   12064         348 :         struct sn_state *s = (struct sn_state  *)state;
   12065         348 :         int i = s->i;
   12066             : 
   12067             : #if 0
   12068             :         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
   12069             :                 i, finfo->name, finfo->short_name);
   12070             : #endif
   12071             : 
   12072         348 :         if (strchr(force_shortname_chars, i)) {
   12073          36 :                 if (!finfo->short_name) {
   12074             :                         /* Shortname not created when it should be. */
   12075           0 :                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
   12076             :                                 __location__, finfo->name, i);
   12077           0 :                         s->val = true;
   12078             :                 }
   12079         312 :         } else if (finfo->short_name){
   12080             :                 /* Shortname created when it should not be. */
   12081           0 :                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
   12082             :                         __location__, finfo->short_name, finfo->name);
   12083           0 :                 s->val = true;
   12084             :         }
   12085         348 :         s->matched += 1;
   12086         348 :         return NT_STATUS_OK;
   12087             : }
   12088             : 
   12089           4 : static bool run_shortname_test(int dummy)
   12090             : {
   12091           0 :         static struct cli_state *cli;
   12092           4 :         bool correct = True;
   12093           0 :         int i;
   12094           0 :         struct sn_state s;
   12095           0 :         char fname[40];
   12096           0 :         NTSTATUS status;
   12097             : 
   12098           4 :         printf("starting shortname test\n");
   12099             : 
   12100           4 :         if (!torture_open_connection(&cli, 0)) {
   12101           0 :                 return False;
   12102             :         }
   12103             : 
   12104           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12105             : 
   12106           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12107           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12108           4 :         cli_rmdir(cli, "\\shortname");
   12109             : 
   12110           4 :         status = cli_mkdir(cli, "\\shortname");
   12111           4 :         if (!NT_STATUS_IS_OK(status)) {
   12112           0 :                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
   12113             :                         __location__, nt_errstr(status));
   12114           0 :                 correct = false;
   12115           0 :                 goto out;
   12116             :         }
   12117             : 
   12118           4 :         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
   12119           0 :                 correct = false;
   12120           0 :                 goto out;
   12121             :         }
   12122           4 :         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
   12123           0 :                 correct = false;
   12124           0 :                 goto out;
   12125             :         }
   12126             : 
   12127           4 :         s.val = false;
   12128             : 
   12129         388 :         for (i = 32; i < 128; i++) {
   12130         384 :                 uint16_t fnum = (uint16_t)-1;
   12131             : 
   12132         384 :                 s.i = i;
   12133             : 
   12134         384 :                 if (strchr(illegal_chars, i)) {
   12135          36 :                         continue;
   12136             :                 }
   12137         348 :                 fname[15] = i;
   12138             : 
   12139         348 :                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
   12140             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
   12141             :                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
   12142         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12143           0 :                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
   12144             :                                 __location__, fname, nt_errstr(status));
   12145           0 :                         correct = false;
   12146           0 :                         goto out;
   12147             :                 }
   12148         348 :                 cli_close(cli, fnum);
   12149             : 
   12150         348 :                 s.matched = 0;
   12151         348 :                 status = cli_list(cli, "\\shortname\\test*.*", 0,
   12152             :                                   shortname_list_fn, &s);
   12153         348 :                 if (s.matched != 1) {
   12154           0 :                         d_printf("(%s) failed to list %s: %s\n",
   12155             :                                 __location__, fname, nt_errstr(status));
   12156           0 :                         correct = false;
   12157           0 :                         goto out;
   12158             :                 }
   12159             : 
   12160         348 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12161         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12162           0 :                         d_printf("(%s) failed to delete %s: %s\n",
   12163             :                                 __location__, fname, nt_errstr(status));
   12164           0 :                         correct = false;
   12165           0 :                         goto out;
   12166             :                 }
   12167             : 
   12168         348 :                 if (s.val) {
   12169           0 :                         correct = false;
   12170           0 :                         goto out;
   12171             :                 }
   12172             :         }
   12173             : 
   12174           4 :   out:
   12175             : 
   12176           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12177           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12178           4 :         cli_rmdir(cli, "\\shortname");
   12179           4 :         torture_close_connection(cli);
   12180           4 :         return correct;
   12181             : }
   12182             : 
   12183             : TLDAPRC callback_code;
   12184             : 
   12185         478 : static void pagedsearch_cb(struct tevent_req *req)
   12186             : {
   12187           0 :         TLDAPRC rc;
   12188           0 :         struct tldap_message *msg;
   12189           0 :         char *dn;
   12190             : 
   12191         478 :         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
   12192         478 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12193           0 :                 d_printf("tldap_search_paged_recv failed: %s\n",
   12194             :                          tldap_rc2string(rc));
   12195           0 :                 callback_code = rc;
   12196           0 :                 return;
   12197             :         }
   12198         478 :         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
   12199           8 :                 TALLOC_FREE(msg);
   12200           8 :                 return;
   12201             :         }
   12202         470 :         if (!tldap_entry_dn(msg, &dn)) {
   12203           0 :                 d_printf("tldap_entry_dn failed\n");
   12204           0 :                 return;
   12205             :         }
   12206         470 :         d_printf("%s\n", dn);
   12207         470 :         TALLOC_FREE(msg);
   12208             : }
   12209             : 
   12210             : enum tldap_extended_val {
   12211             :         EXTENDED_ZERO = 0,
   12212             :         EXTENDED_ONE = 1,
   12213             :         EXTENDED_NONE = 2,
   12214             : };
   12215             : 
   12216             : /*
   12217             :  * Construct an extended dn control with either no value, 0 or 1
   12218             :  *
   12219             :  * No value and 0 are equivalent (non-hyphenated GUID)
   12220             :  * 1 has the hyphenated GUID
   12221             :  */
   12222             : static struct tldap_control *
   12223           6 : tldap_build_extended_control(enum tldap_extended_val val)
   12224             : {
   12225           0 :         struct tldap_control empty_control;
   12226           0 :         struct asn1_data *data;
   12227             : 
   12228           6 :         ZERO_STRUCT(empty_control);
   12229             : 
   12230           6 :         if (val != EXTENDED_NONE) {
   12231           4 :                 data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
   12232             : 
   12233           4 :                 if (!data) {
   12234           0 :                         return NULL;
   12235             :                 }
   12236             : 
   12237           4 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
   12238           0 :                         return NULL;
   12239             :                 }
   12240             : 
   12241           4 :                 if (!asn1_write_Integer(data, (int)val)) {
   12242           0 :                         return NULL;
   12243             :                 }
   12244             : 
   12245           4 :                 if (!asn1_pop_tag(data)) {
   12246           0 :                         return NULL;
   12247             :                 }
   12248             : 
   12249           4 :                 if (!asn1_blob(data, &empty_control.value)) {
   12250           0 :                         return NULL;
   12251             :                 }
   12252             :         }
   12253             : 
   12254           6 :         empty_control.oid = "1.2.840.113556.1.4.529";
   12255           6 :         empty_control.critical = true;
   12256             : 
   12257           6 :         return tldap_add_control(talloc_tos(), NULL, 0, &empty_control);
   12258             : 
   12259             : }
   12260             : 
   12261           6 : static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn,
   12262             :                                       enum tldap_extended_val control_val)
   12263             : {
   12264           6 :         struct tldap_control *control = tldap_build_extended_control(control_val);
   12265           6 :         char *dn = NULL;
   12266           0 :         struct tldap_message **msg;
   12267           0 :         TLDAPRC rc;
   12268             : 
   12269           6 :         rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE,
   12270             :                           "(objectClass=*)", NULL, 0, 0,
   12271             :                           control, 1, NULL,
   12272             :                           0, 0, 0, 0, talloc_tos(), &msg);
   12273           6 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12274           0 :                 d_printf("tldap_search for domain DN failed: %s\n",
   12275             :                          tldap_errstr(talloc_tos(), ld, rc));
   12276           0 :                 return false;
   12277             :         }
   12278             : 
   12279           6 :         if (!tldap_entry_dn(msg[0], &dn)) {
   12280           0 :                 d_printf("tldap_search domain DN fetch failed: %s\n",
   12281             :                          tldap_errstr(talloc_tos(), ld, rc));
   12282           0 :                 return false;
   12283             :         }
   12284             : 
   12285           6 :         d_printf("%s\n", dn);
   12286             :         {
   12287           0 :                 uint32_t time_low;
   12288           0 :                 uint32_t time_mid, time_hi_and_version;
   12289           0 :                 uint32_t clock_seq[2];
   12290           0 :                 uint32_t node[6];
   12291           0 :                 char next;
   12292             : 
   12293           6 :                 switch (control_val) {
   12294           4 :                 case EXTENDED_NONE:
   12295             :                 case EXTENDED_ZERO:
   12296             :                         /*
   12297             :                          * When reading GUIDs with hyphens, scanf will treat
   12298             :                          * hyphen as a hex character (and counts as part of the
   12299             :                          * width). This creates leftover GUID string which we
   12300             :                          * check will for with 'next' and closing '>'.
   12301             :                          */
   12302           4 :                         if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
   12303             :                                          &time_low, &time_mid,
   12304             :                                          &time_hi_and_version, &clock_seq[0],
   12305             :                                          &clock_seq[1], &node[0], &node[1],
   12306             :                                          &node[2], &node[3], &node[4],
   12307             :                                          &node[5], &next)) {
   12308             :                                 /* This GUID is good */
   12309             :                         } else {
   12310           0 :                                 d_printf("GUID format in control (no hyphens) doesn't match output\n");
   12311           0 :                                 return false;
   12312             :                         }
   12313             : 
   12314           4 :                         break;
   12315           2 :                 case EXTENDED_ONE:
   12316           2 :                         if (12 == sscanf(dn,
   12317             :                                          "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
   12318             :                                          &time_low, &time_mid,
   12319             :                                          &time_hi_and_version, &clock_seq[0],
   12320             :                                          &clock_seq[1], &node[0], &node[1],
   12321             :                                          &node[2], &node[3], &node[4],
   12322             :                                          &node[5], &next)) {
   12323             :                                 /* This GUID is good */
   12324             :                         } else {
   12325           0 :                                 d_printf("GUID format in control (with hyphens) doesn't match output\n");
   12326           0 :                                 return false;
   12327             :                         }
   12328             : 
   12329           2 :                         break;
   12330           0 :                 default:
   12331           0 :                         return false;
   12332             :                 }
   12333             :         }
   12334             : 
   12335           6 :         return true;
   12336             : }
   12337             : 
   12338           2 : static bool run_tldap(int dummy)
   12339             : {
   12340           0 :         struct tldap_context *ld;
   12341           0 :         int fd;
   12342           0 :         TLDAPRC rc;
   12343           0 :         NTSTATUS status;
   12344           0 :         struct sockaddr_storage addr;
   12345           0 :         struct tevent_context *ev;
   12346           0 :         struct tevent_req *req;
   12347           0 :         char *basedn;
   12348           0 :         const char *filter;
   12349             : 
   12350           2 :         if (!resolve_name(host, &addr, 0, false)) {
   12351           0 :                 d_printf("could not find host %s\n", host);
   12352           0 :                 return false;
   12353             :         }
   12354           2 :         status = open_socket_out(&addr, 389, 9999, &fd);
   12355           2 :         if (!NT_STATUS_IS_OK(status)) {
   12356           0 :                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
   12357           0 :                 return false;
   12358             :         }
   12359             : 
   12360           2 :         ld = tldap_context_create(talloc_tos(), fd);
   12361           2 :         if (ld == NULL) {
   12362           0 :                 close(fd);
   12363           0 :                 d_printf("tldap_context_create failed\n");
   12364           0 :                 return false;
   12365             :         }
   12366             : 
   12367           2 :         rc = tldap_fetch_rootdse(ld);
   12368           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12369           0 :                 d_printf("tldap_fetch_rootdse failed: %s\n",
   12370             :                          tldap_errstr(talloc_tos(), ld, rc));
   12371           0 :                 return false;
   12372             :         }
   12373             : 
   12374           2 :         basedn = tldap_talloc_single_attribute(
   12375             :                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
   12376           2 :         if (basedn == NULL) {
   12377           0 :                 d_printf("no defaultNamingContext\n");
   12378           0 :                 return false;
   12379             :         }
   12380           2 :         d_printf("defaultNamingContext: %s\n", basedn);
   12381             : 
   12382           2 :         ev = samba_tevent_context_init(talloc_tos());
   12383           2 :         if (ev == NULL) {
   12384           0 :                 d_printf("tevent_context_init failed\n");
   12385           0 :                 return false;
   12386             :         }
   12387             : 
   12388           2 :         rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL,
   12389             :                                loadparm_init_s3(talloc_tos(),
   12390             :                                                 loadparm_s3_helpers()),
   12391             :                                GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
   12392             : 
   12393           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12394           0 :                 d_printf("tldap_gensec_bind failed\n");
   12395           0 :                 return false;
   12396             :         }
   12397             : 
   12398           2 :         callback_code = TLDAP_SUCCESS;
   12399             : 
   12400           2 :         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
   12401             :                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
   12402             :                                       NULL, 0, 0,
   12403             :                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
   12404           2 :         if (req == NULL) {
   12405           0 :                 d_printf("tldap_search_paged_send failed\n");
   12406           0 :                 return false;
   12407             :         }
   12408           2 :         tevent_req_set_callback(req, pagedsearch_cb, NULL);
   12409             : 
   12410           2 :         tevent_req_poll(req, ev);
   12411             : 
   12412           2 :         TALLOC_FREE(req);
   12413             : 
   12414           2 :         rc = callback_code;
   12415             : 
   12416           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12417           0 :                 d_printf("tldap_search with paging failed: %s\n",
   12418             :                          tldap_errstr(talloc_tos(), ld, rc));
   12419           0 :                 return false;
   12420             :         }
   12421             : 
   12422             :         /* test search filters against rootDSE */
   12423           2 :         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
   12424             :                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
   12425             : 
   12426           2 :         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
   12427             :                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
   12428             :                           talloc_tos(), NULL);
   12429           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12430           0 :                 d_printf("tldap_search with complex filter failed: %s\n",
   12431             :                          tldap_errstr(talloc_tos(), ld, rc));
   12432           0 :                 return false;
   12433             :         }
   12434             : 
   12435             :         /*
   12436             :          * Tests to check for regression of:
   12437             :          *
   12438             :          * https://bugzilla.samba.org/show_bug.cgi?id=14029
   12439             :          *
   12440             :          * TLDAP used here to pick apart the original string DN (with GUID)
   12441             :          */
   12442           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) {
   12443           0 :                 d_printf("tldap_search with extended dn (no val) failed: %s\n",
   12444             :                          tldap_errstr(talloc_tos(), ld, rc));
   12445           0 :                 return false;
   12446             :         }
   12447           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) {
   12448           0 :                 d_printf("tldap_search with extended dn (0) failed: %s\n",
   12449             :                          tldap_errstr(talloc_tos(), ld, rc));
   12450           0 :                 return false;
   12451             :         }
   12452           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) {
   12453           0 :                 d_printf("tldap_search with extended dn (1) failed: %s\n",
   12454             :                          tldap_errstr(talloc_tos(), ld, rc));
   12455           0 :                 return false;
   12456             :         }
   12457             : 
   12458           2 :         TALLOC_FREE(ld);
   12459           2 :         return true;
   12460             : }
   12461             : 
   12462             : /* Torture test to ensure no regression of :
   12463             : https://bugzilla.samba.org/show_bug.cgi?id=7084
   12464             : */
   12465             : 
   12466           4 : static bool run_dir_createtime(int dummy)
   12467             : {
   12468           0 :         struct cli_state *cli;
   12469           4 :         const char *dname = "\\testdir_createtime";
   12470           4 :         const char *fname = "\\testdir_createtime\\testfile";
   12471           0 :         NTSTATUS status;
   12472           0 :         struct timespec create_time;
   12473           0 :         struct timespec create_time1;
   12474           0 :         uint16_t fnum;
   12475           4 :         bool ret = false;
   12476           0 :         uint64_t ino;
   12477             : 
   12478           4 :         if (!torture_open_connection(&cli, 0)) {
   12479           0 :                 return false;
   12480             :         }
   12481             : 
   12482           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12483             :                 /* Ensure ino is zero, SMB2 gets a real one. */
   12484           0 :                 ino = 0;
   12485             :         } else {
   12486             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
   12487           4 :                 ino = (uint64_t)-1;
   12488             :         }
   12489             : 
   12490           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12491           4 :         cli_rmdir(cli, dname);
   12492             : 
   12493           4 :         status = cli_mkdir(cli, dname);
   12494           4 :         if (!NT_STATUS_IS_OK(status)) {
   12495           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12496           0 :                 goto out;
   12497             :         }
   12498             : 
   12499           4 :         status = cli_qpathinfo2(cli,
   12500             :                                 dname,
   12501             :                                 &create_time,
   12502             :                                 NULL,
   12503             :                                 NULL,
   12504             :                                 NULL,
   12505             :                                 NULL,
   12506             :                                 NULL,
   12507             :                                 &ino,
   12508             :                                 NULL);
   12509           4 :         if (!NT_STATUS_IS_OK(status)) {
   12510           0 :                 printf("cli_qpathinfo2 returned %s\n",
   12511             :                        nt_errstr(status));
   12512           0 :                 goto out;
   12513             :         }
   12514             : 
   12515           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12516             :                 /* SMB2 should always return an inode. */
   12517           0 :                 if (ino == 0) {
   12518           0 :                         printf("SMB2 bad inode (0)\n");
   12519           0 :                         goto out;
   12520             :                 }
   12521             :         } else {
   12522             :                 /* SMB1 must always return zero here. */
   12523           4 :                 if (ino != 0) {
   12524           0 :                         printf("SMB1 bad inode (!0)\n");
   12525           0 :                         goto out;
   12526             :                 }
   12527             :         }
   12528             : 
   12529             :         /* Sleep 3 seconds, then create a file. */
   12530           4 :         sleep(3);
   12531             : 
   12532           4 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
   12533             :                          DENY_NONE, &fnum);
   12534           4 :         if (!NT_STATUS_IS_OK(status)) {
   12535           0 :                 printf("cli_openx failed: %s\n", nt_errstr(status));
   12536           0 :                 goto out;
   12537             :         }
   12538             : 
   12539           4 :         status = cli_qpathinfo2(cli,
   12540             :                                 dname,
   12541             :                                 &create_time1,
   12542             :                                 NULL,
   12543             :                                 NULL,
   12544             :                                 NULL,
   12545             :                                 NULL,
   12546             :                                 NULL,
   12547             :                                 NULL,
   12548             :                                 NULL);
   12549           4 :         if (!NT_STATUS_IS_OK(status)) {
   12550           0 :                 printf("cli_qpathinfo2 (2) returned %s\n",
   12551             :                        nt_errstr(status));
   12552           0 :                 goto out;
   12553             :         }
   12554             : 
   12555           4 :         if (timespec_compare(&create_time1, &create_time)) {
   12556           0 :                 printf("run_dir_createtime: create time was updated (error)\n");
   12557             :         } else {
   12558           4 :                 printf("run_dir_createtime: create time was not updated (correct)\n");
   12559           4 :                 ret = true;
   12560             :         }
   12561             : 
   12562           4 :   out:
   12563             : 
   12564           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12565           4 :         cli_rmdir(cli, dname);
   12566           4 :         if (!torture_close_connection(cli)) {
   12567           0 :                 ret = false;
   12568             :         }
   12569           4 :         return ret;
   12570             : }
   12571             : 
   12572             : 
   12573           4 : static bool run_streamerror(int dummy)
   12574             : {
   12575           0 :         struct cli_state *cli;
   12576           4 :         const char *dname = "\\testdir_streamerror";
   12577           4 :         const char *streamname =
   12578             :                 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
   12579           0 :         NTSTATUS status;
   12580           0 :         time_t change_time, access_time, write_time;
   12581           0 :         off_t size;
   12582           0 :         uint16_t fnum;
   12583           0 :         uint32_t attr;
   12584           4 :         bool ret = true;
   12585             : 
   12586           4 :         if (!torture_open_connection(&cli, 0)) {
   12587           0 :                 return false;
   12588             :         }
   12589             : 
   12590           4 :         torture_deltree(cli, dname);
   12591             : 
   12592           4 :         status = cli_mkdir(cli, dname);
   12593           4 :         if (!NT_STATUS_IS_OK(status)) {
   12594           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12595           0 :                 return false;
   12596             :         }
   12597             : 
   12598           4 :         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
   12599             :                                 &write_time, &size, &attr);
   12600           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12601           0 :                 printf("pathinfo returned %s, expected "
   12602             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12603             :                        nt_errstr(status));
   12604           0 :                 ret = false;
   12605             :         }
   12606             : 
   12607           4 :         status = cli_ntcreate(cli, streamname, 0x16,
   12608             :                               FILE_READ_DATA|FILE_READ_EA|
   12609             :                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
   12610             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
   12611             :                               FILE_OPEN, 0, 0, &fnum, NULL);
   12612             : 
   12613           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12614           0 :                 printf("ntcreate returned %s, expected "
   12615             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12616             :                        nt_errstr(status));
   12617           0 :                 ret = false;
   12618             :         }
   12619             : 
   12620             : 
   12621           4 :         cli_rmdir(cli, dname);
   12622           4 :         return ret;
   12623             : }
   12624             : 
   12625             : struct pidtest_state {
   12626             :         bool success;
   12627             :         uint16_t vwv[1];
   12628             :         DATA_BLOB data;
   12629             : };
   12630             : 
   12631             : static void pid_echo_done(struct tevent_req *subreq);
   12632             : 
   12633           4 : static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
   12634             :                         struct tevent_context *ev,
   12635             :                         struct cli_state *cli)
   12636             : {
   12637           0 :         struct tevent_req *req, *subreq;
   12638           0 :         struct pidtest_state *state;
   12639             : 
   12640           4 :         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
   12641           4 :         if (req == NULL) {
   12642           0 :                 return NULL;
   12643             :         }
   12644             : 
   12645           4 :         SSVAL(state->vwv, 0, 1);
   12646           4 :         state->data = data_blob_const("hello", 5);
   12647             : 
   12648           4 :         subreq = smb1cli_req_send(state,
   12649             :                                 ev,
   12650             :                                 cli->conn,
   12651             :                                 SMBecho,
   12652             :                                 0, 0, /* *_flags */
   12653             :                                 0, 0, /* *_flags2 */
   12654           4 :                                 cli->timeout,
   12655             :                                 0xDEADBEEF, /* pid */
   12656             :                                 NULL, /* tcon */
   12657             :                                 NULL, /* session */
   12658           4 :                                 ARRAY_SIZE(state->vwv), state->vwv,
   12659           4 :                                 state->data.length, state->data.data);
   12660             : 
   12661           4 :         if (tevent_req_nomem(subreq, req)) {
   12662           0 :                 return tevent_req_post(req, ev);
   12663             :         }
   12664           4 :         tevent_req_set_callback(subreq, pid_echo_done, req);
   12665           4 :         return req;
   12666             : }
   12667             : 
   12668           4 : static void pid_echo_done(struct tevent_req *subreq)
   12669             : {
   12670           4 :         struct tevent_req *req = tevent_req_callback_data(
   12671             :                 subreq, struct tevent_req);
   12672           4 :         struct pidtest_state *state = tevent_req_data(
   12673             :                 req, struct pidtest_state);
   12674           0 :         NTSTATUS status;
   12675           0 :         uint32_t num_bytes;
   12676           4 :         uint8_t *bytes = NULL;
   12677           4 :         struct iovec *recv_iov = NULL;
   12678           4 :         uint8_t *phdr = NULL;
   12679           4 :         uint16_t pidlow = 0;
   12680           4 :         uint16_t pidhigh = 0;
   12681           4 :         struct smb1cli_req_expected_response expected[] = {
   12682             :         {
   12683             :                 .status = NT_STATUS_OK,
   12684             :                 .wct    = 1,
   12685             :         },
   12686             :         };
   12687             : 
   12688           4 :         status = smb1cli_req_recv(subreq, state,
   12689             :                                 &recv_iov,
   12690             :                                 &phdr,
   12691             :                                 NULL, /* pwct */
   12692             :                                 NULL, /* pvwv */
   12693             :                                 NULL, /* pvwv_offset */
   12694             :                                 &num_bytes,
   12695             :                                 &bytes,
   12696             :                                 NULL, /* pbytes_offset */
   12697             :                                 NULL, /* pinbuf */
   12698             :                                 expected, ARRAY_SIZE(expected));
   12699             : 
   12700           4 :         TALLOC_FREE(subreq);
   12701             : 
   12702           4 :         if (!NT_STATUS_IS_OK(status)) {
   12703           0 :                 tevent_req_nterror(req, status);
   12704           0 :                 return;
   12705             :         }
   12706             : 
   12707           4 :         if (num_bytes != state->data.length) {
   12708           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12709           0 :                 return;
   12710             :         }
   12711             : 
   12712           4 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
   12713           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12714           0 :                 return;
   12715             :         }
   12716             : 
   12717             :         /* Check pid low/high == DEADBEEF */
   12718           4 :         pidlow = SVAL(phdr, HDR_PID);
   12719           4 :         if (pidlow != 0xBEEF){
   12720           0 :                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
   12721             :                         (unsigned int)pidlow);
   12722           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12723           0 :                 return;
   12724             :         }
   12725           4 :         pidhigh = SVAL(phdr, HDR_PIDHIGH);
   12726           4 :         if (pidhigh != 0xDEAD){
   12727           0 :                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
   12728             :                         (unsigned int)pidhigh);
   12729           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12730           0 :                 return;
   12731             :         }
   12732             : 
   12733           4 :         tevent_req_done(req);
   12734             : }
   12735             : 
   12736           4 : static NTSTATUS pid_echo_recv(struct tevent_req *req)
   12737             : {
   12738           4 :         return tevent_req_simple_recv_ntstatus(req);
   12739             : }
   12740             : 
   12741           4 : static bool run_pidhigh(int dummy)
   12742             : {
   12743           4 :         bool success = false;
   12744           4 :         struct cli_state *cli = NULL;
   12745           0 :         NTSTATUS status;
   12746           4 :         struct tevent_context *ev = NULL;
   12747           4 :         struct tevent_req *req = NULL;
   12748           4 :         TALLOC_CTX *frame = talloc_stackframe();
   12749             : 
   12750           4 :         printf("starting pid high test\n");
   12751           4 :         if (!torture_open_connection(&cli, 0)) {
   12752           0 :                 return false;
   12753             :         }
   12754           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12755             : 
   12756           4 :         ev = samba_tevent_context_init(frame);
   12757           4 :         if (ev == NULL) {
   12758           0 :                 goto fail;
   12759             :         }
   12760             : 
   12761           4 :         req = pid_echo_send(frame, ev, cli);
   12762           4 :         if (req == NULL) {
   12763           0 :                 goto fail;
   12764             :         }
   12765             : 
   12766           4 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
   12767           0 :                 goto fail;
   12768             :         }
   12769             : 
   12770           4 :         status = pid_echo_recv(req);
   12771           4 :         if (NT_STATUS_IS_OK(status)) {
   12772           4 :                 printf("pid high test ok\n");
   12773           4 :                 success = true;
   12774             :         }
   12775             : 
   12776           0 :  fail:
   12777             : 
   12778           4 :         TALLOC_FREE(frame);
   12779           4 :         torture_close_connection(cli);
   12780           4 :         return success;
   12781             : }
   12782             : 
   12783             : /*
   12784             :   Test Windows open on a bad POSIX symlink.
   12785             :  */
   12786           4 : static bool run_symlink_open_test(int dummy)
   12787             : {
   12788           0 :         static struct cli_state *cli;
   12789           4 :         const char *fname = "non_existant_file";
   12790           4 :         const char *sname = "dangling_symlink";
   12791           4 :         uint16_t fnum = (uint16_t)-1;
   12792           4 :         bool correct = false;
   12793           0 :         NTSTATUS status;
   12794           4 :         TALLOC_CTX *frame = NULL;
   12795             : 
   12796           4 :         frame = talloc_stackframe();
   12797             : 
   12798           4 :         printf("Starting Windows bad symlink open test\n");
   12799             : 
   12800           4 :         if (!torture_open_connection(&cli, 0)) {
   12801           0 :                 TALLOC_FREE(frame);
   12802           0 :                 return false;
   12803             :         }
   12804             : 
   12805           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12806             : 
   12807           4 :         status = torture_setup_unix_extensions(cli);
   12808           4 :         if (!NT_STATUS_IS_OK(status)) {
   12809           0 :                 TALLOC_FREE(frame);
   12810           0 :                 return false;
   12811             :         }
   12812             : 
   12813             :         /* Ensure nothing exists. */
   12814           4 :         cli_setatr(cli, fname, 0, 0);
   12815           4 :         cli_posix_unlink(cli, fname);
   12816           4 :         cli_setatr(cli, sname, 0, 0);
   12817           4 :         cli_posix_unlink(cli, sname);
   12818             : 
   12819             :         /* Create a symlink pointing nowhere. */
   12820           4 :         status = cli_posix_symlink(cli, fname, sname);
   12821           4 :         if (!NT_STATUS_IS_OK(status)) {
   12822           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
   12823             :                         sname,
   12824             :                         fname,
   12825             :                         nt_errstr(status));
   12826           0 :                 goto out;
   12827             :         }
   12828             : 
   12829             :         /* Now ensure that a Windows open doesn't hang. */
   12830           4 :         status = cli_ntcreate(cli,
   12831             :                         sname,
   12832             :                         0,
   12833             :                         FILE_READ_DATA|FILE_WRITE_DATA,
   12834             :                         0,
   12835             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   12836             :                         FILE_OPEN_IF,
   12837             :                         0x0,
   12838             :                         0x0,
   12839             :                         &fnum,
   12840             :                         NULL);
   12841             : 
   12842             :         /*
   12843             :          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
   12844             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
   12845             :          * we use O_NOFOLLOW on the server or not.
   12846             :          */
   12847           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
   12848           0 :             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
   12849             :         {
   12850           4 :                 correct = true;
   12851             :         } else {
   12852           0 :                 printf("cli_ntcreate of %s returned %s - should return"
   12853             :                                 " either (%s) or (%s)\n",
   12854             :                         sname,
   12855             :                         nt_errstr(status),
   12856           0 :                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
   12857           0 :                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
   12858           0 :                 goto out;
   12859             :         }
   12860             : 
   12861           4 :         correct = true;
   12862             : 
   12863           4 :   out:
   12864             : 
   12865           4 :         if (fnum != (uint16_t)-1) {
   12866           0 :                 cli_close(cli, fnum);
   12867           0 :                 fnum = (uint16_t)-1;
   12868             :         }
   12869             : 
   12870           4 :         cli_setatr(cli, sname, 0, 0);
   12871           4 :         cli_posix_unlink(cli, sname);
   12872           4 :         cli_setatr(cli, fname, 0, 0);
   12873           4 :         cli_posix_unlink(cli, fname);
   12874             : 
   12875           4 :         if (!torture_close_connection(cli)) {
   12876           0 :                 correct = false;
   12877             :         }
   12878             : 
   12879           4 :         TALLOC_FREE(frame);
   12880           4 :         return correct;
   12881             : }
   12882             : 
   12883          16 : static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
   12884             :                                         const char *name,
   12885             :                                         void *state)
   12886             : {
   12887          16 :         char **mangled_name_return = (char **)state;
   12888          16 :         bool is_mangled = strchr(finfo->name, '~');
   12889             : 
   12890          16 :         if (is_mangled) {
   12891           8 :                 *mangled_name_return = talloc_strdup(NULL, finfo->name);
   12892           8 :                 if (*mangled_name_return == NULL) {
   12893           0 :                         return NT_STATUS_NO_MEMORY;
   12894             :                 }
   12895             :         }
   12896          16 :         return NT_STATUS_OK;
   12897             : }
   12898             : 
   12899           4 : static bool run_smb1_wild_mangle_unlink_test(int dummy)
   12900             : {
   12901           0 :         static struct cli_state *cli_posix = NULL;
   12902           0 :         static struct cli_state *cli = NULL;
   12903           4 :         uint16_t fnum = (uint16_t)-1;
   12904           4 :         bool correct = false;
   12905           4 :         const char *dname = "smb1_wild_mangle_unlink";
   12906           4 :         const char *aname = "smb1_wild_mangle_unlink/a";
   12907           4 :         const char *star_name = "smb1_wild_mangle_unlink/*";
   12908           4 :         char *windows_unlink_name = NULL;
   12909           4 :         char *mangled_name = NULL;
   12910           0 :         NTSTATUS status;
   12911             : 
   12912           4 :         printf("Starting SMB1 wild mangle unlink test\n");
   12913             : 
   12914             :         /* Open a Windows connection. */
   12915           4 :         if (!torture_open_connection(&cli, 0)) {
   12916           0 :                 return false;
   12917             :         }
   12918             : 
   12919           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12920             : 
   12921             :         /* Open a POSIX connection. */
   12922           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   12923           0 :                 goto out;
   12924             :         }
   12925             : 
   12926           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12927             : 
   12928           4 :         status = torture_setup_unix_extensions(cli_posix);
   12929           4 :         if (!NT_STATUS_IS_OK(status)) {
   12930           0 :                 printf("server doesn't support POSIX\n");
   12931           0 :                 goto out;
   12932             :         }
   12933             : 
   12934             :         /* Start fresh. */
   12935           4 :         torture_deltree(cli, dname);
   12936             : 
   12937             :         /*
   12938             :          * Create two files - 'a' and '*'.
   12939             :          * We need POSIX extensions for this as '*'
   12940             :          * is not a valid Windows name.
   12941             :          */
   12942             : 
   12943           4 :         status = cli_mkdir(cli, dname);
   12944           4 :         if (!NT_STATUS_IS_OK(status)) {
   12945           0 :                 printf("cli_mkdir of %s returned %s\n",
   12946             :                         dname,
   12947             :                         nt_errstr(status));
   12948           0 :                 goto out;
   12949             :         }
   12950             : 
   12951           4 :         status = cli_posix_open(cli_posix,
   12952             :                                 aname,
   12953             :                                 O_RDWR|O_CREAT|O_EXCL,
   12954             :                                 0660,
   12955             :                                 &fnum);
   12956           4 :         if (!NT_STATUS_IS_OK(status)) {
   12957           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12958             :                         aname,
   12959             :                         nt_errstr(status));
   12960           0 :                 goto out;
   12961             :         }
   12962           4 :         status = cli_close(cli_posix, fnum);
   12963           4 :         if (!NT_STATUS_IS_OK(status)) {
   12964           0 :                 goto out;
   12965             :         }
   12966           4 :         status = cli_posix_open(cli_posix,
   12967             :                                 star_name,
   12968             :                                 O_RDWR|O_CREAT|O_EXCL,
   12969             :                                 0660,
   12970             :                                 &fnum);
   12971           4 :         if (!NT_STATUS_IS_OK(status)) {
   12972           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12973             :                         star_name,
   12974             :                         nt_errstr(status));
   12975           0 :                 goto out;
   12976             :         }
   12977           4 :         status = cli_close(cli_posix, fnum);
   12978           4 :         if (!NT_STATUS_IS_OK(status)) {
   12979           0 :                 goto out;
   12980             :         }
   12981             : 
   12982           4 :         status = cli_list(cli,
   12983             :                         star_name,
   12984             :                         0,
   12985             :                         smb1_wild_mangle_list_fn,
   12986             :                         &mangled_name);
   12987           4 :         if (!NT_STATUS_IS_OK(status)) {
   12988           0 :                 printf("cli_list of %s returned %s\n",
   12989             :                         star_name,
   12990             :                         nt_errstr(status));
   12991           0 :                 goto out;
   12992             :         }
   12993             : 
   12994           4 :         if (mangled_name == NULL) {
   12995           0 :                 goto out;
   12996             :         }
   12997             : 
   12998           4 :         printf("mangled_name = %s\n",
   12999             :                 mangled_name);
   13000             : 
   13001             :         /*
   13002             :          * Try a Windows unlink with the mangled name.
   13003             :          * This should *NOT* unlink the 'a' name.
   13004             :          */
   13005             : 
   13006           4 :         windows_unlink_name = talloc_asprintf(cli_posix,
   13007             :                                         "%s\\%s",
   13008             :                                         dname,
   13009             :                                         mangled_name);
   13010             : 
   13011           4 :         status = cli_unlink(cli, windows_unlink_name, 0);
   13012           4 :         if (!NT_STATUS_IS_OK(status)) {
   13013           0 :                 printf("cli_unlink of %s returned %s\n",
   13014             :                         windows_unlink_name,
   13015             :                         nt_errstr(status));
   13016           0 :                 goto out;
   13017             :         }
   13018             : 
   13019             :         /* Does 'a' still exist ? */
   13020           4 :         status = cli_posix_open(cli_posix,
   13021             :                                 aname,
   13022             :                                 O_RDONLY,
   13023             :                                 0,
   13024             :                                 &fnum);
   13025           4 :         if (!NT_STATUS_IS_OK(status)) {
   13026           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13027             :                         aname,
   13028             :                         nt_errstr(status));
   13029           0 :                 goto out;
   13030             :         }
   13031             : 
   13032           4 :         status = cli_close(cli_posix, fnum);
   13033           4 :         if (!NT_STATUS_IS_OK(status)) {
   13034           0 :                 goto out;
   13035             :         }
   13036             : 
   13037           4 :         correct = true;
   13038             : 
   13039           4 :   out:
   13040             : 
   13041           4 :         TALLOC_FREE(windows_unlink_name);
   13042           4 :         TALLOC_FREE(mangled_name);
   13043             : 
   13044           4 :         if (cli != NULL) {
   13045           4 :                 torture_deltree(cli, dname);
   13046           4 :                 torture_close_connection(cli);
   13047             :         }
   13048             : 
   13049           4 :         if (cli_posix != NULL) {
   13050           4 :                 torture_close_connection(cli_posix);
   13051             :         }
   13052             : 
   13053           4 :         return correct;
   13054             : }
   13055             : 
   13056           4 : static bool run_smb1_wild_mangle_rename_test(int dummy)
   13057             : {
   13058           0 :         static struct cli_state *cli_posix = NULL;
   13059           0 :         static struct cli_state *cli = NULL;
   13060           4 :         uint16_t fnum = (uint16_t)-1;
   13061           4 :         bool correct = false;
   13062           4 :         const char *dname = "smb1_wild_mangle_rename";
   13063           4 :         const char *fooname = "smb1_wild_mangle_rename/foo";
   13064           4 :         const char *foostar_name = "smb1_wild_mangle_rename/fo*";
   13065           4 :         const char *wild_name = "smb1_wild_mangle_rename/*";
   13066           4 :         char *windows_rename_src = NULL;
   13067           4 :         const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
   13068           4 :         char *mangled_name = NULL;
   13069           0 :         NTSTATUS status;
   13070             : 
   13071           4 :         printf("Starting SMB1 wild mangle rename test\n");
   13072             : 
   13073           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   13074           0 :                 return false;
   13075             :         }
   13076             : 
   13077           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   13078             : 
   13079           4 :         status = torture_setup_unix_extensions(cli_posix);
   13080           4 :         if (!NT_STATUS_IS_OK(status)) {
   13081           0 :                 printf("server doesn't support POSIX\n");
   13082           0 :                 return false;
   13083             :         }
   13084             : 
   13085             :         /* Open a Windows connection. */
   13086           4 :         if (!torture_open_connection(&cli, 0)) {
   13087           0 :                 goto out;
   13088             :         }
   13089             : 
   13090           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   13091             : 
   13092             :         /* Ensure we start from fresh. */
   13093           4 :         torture_deltree(cli, dname);
   13094             : 
   13095             :         /*
   13096             :          * Create two files - 'foo' and 'fo*'.
   13097             :          * We need POSIX extensions for this as 'fo*'
   13098             :          * is not a valid Windows name.
   13099             :          */
   13100             : 
   13101           4 :         status = cli_posix_mkdir(cli_posix, dname, 0770);
   13102           4 :         if (!NT_STATUS_IS_OK(status)) {
   13103           0 :                 printf("cli_posix_mkdir of %s returned %s\n",
   13104             :                         dname,
   13105             :                         nt_errstr(status));
   13106           0 :                 goto out;
   13107             :         }
   13108             : 
   13109           4 :         status = cli_posix_open(cli_posix,
   13110             :                                 fooname,
   13111             :                                 O_RDWR|O_CREAT|O_EXCL,
   13112             :                                 0660,
   13113             :                                 &fnum);
   13114           4 :         if (!NT_STATUS_IS_OK(status)) {
   13115           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13116             :                         fooname,
   13117             :                         nt_errstr(status));
   13118           0 :                 goto out;
   13119             :         }
   13120           4 :         status = cli_close(cli_posix, fnum);
   13121           4 :         if (!NT_STATUS_IS_OK(status)) {
   13122           0 :                 goto out;
   13123             :         }
   13124           4 :         status = cli_posix_open(cli_posix,
   13125             :                                 foostar_name,
   13126             :                                 O_RDWR|O_CREAT|O_EXCL,
   13127             :                                 0660,
   13128             :                                 &fnum);
   13129           4 :         if (!NT_STATUS_IS_OK(status)) {
   13130           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13131             :                         foostar_name,
   13132             :                         nt_errstr(status));
   13133           0 :                 goto out;
   13134             :         }
   13135           4 :         status = cli_close(cli_posix, fnum);
   13136           4 :         if (!NT_STATUS_IS_OK(status)) {
   13137           0 :                 goto out;
   13138             :         }
   13139             : 
   13140             :         /*
   13141             :          * Get the mangled name. We can re-use the
   13142             :          * previous smb1_wild_mangle_list_fn for this.
   13143             :          */
   13144             : 
   13145           4 :         status = cli_list(cli,
   13146             :                         wild_name,
   13147             :                         0,
   13148             :                         smb1_wild_mangle_list_fn,
   13149             :                         &mangled_name);
   13150           4 :         if (!NT_STATUS_IS_OK(status)) {
   13151           0 :                 printf("cli_list of %s returned %s\n",
   13152             :                         wild_name,
   13153             :                         nt_errstr(status));
   13154           0 :                 goto out;
   13155             :         }
   13156             : 
   13157           4 :         if (mangled_name == NULL) {
   13158           0 :                 goto out;
   13159             :         }
   13160             : 
   13161           4 :         printf("mangled_name = %s\n",
   13162             :                 mangled_name);
   13163             : 
   13164             :         /*
   13165             :          * Try a Windows rename with the mangled name.
   13166             :          * This should *NOT* rename the 'foo' name.
   13167             :          */
   13168             : 
   13169           4 :         windows_rename_src = talloc_asprintf(cli_posix,
   13170             :                                         "%s\\%s",
   13171             :                                         dname,
   13172             :                                         mangled_name);
   13173             : 
   13174           4 :         status = cli_rename(cli,
   13175             :                         windows_rename_src,
   13176             :                         windows_rename_dst,
   13177             :                         false);
   13178           4 :         if (!NT_STATUS_IS_OK(status)) {
   13179           0 :                 printf("cli_rename of %s -> %s returned %s\n",
   13180             :                         windows_rename_src,
   13181             :                         windows_rename_dst,
   13182             :                         nt_errstr(status));
   13183           0 :                 goto out;
   13184             :         }
   13185             : 
   13186             :         /* Does 'foo' still exist ? */
   13187           4 :         status = cli_posix_open(cli_posix,
   13188             :                                 fooname,
   13189             :                                 O_RDONLY,
   13190             :                                 0,
   13191             :                                 &fnum);
   13192           4 :         if (!NT_STATUS_IS_OK(status)) {
   13193           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13194             :                         fooname,
   13195             :                         nt_errstr(status));
   13196           0 :                 goto out;
   13197             :         }
   13198             : 
   13199           4 :         status = cli_close(cli_posix, fnum);
   13200           4 :         if (!NT_STATUS_IS_OK(status)) {
   13201           0 :                 goto out;
   13202             :         }
   13203             : 
   13204           4 :         correct = true;
   13205             : 
   13206           4 :   out:
   13207             : 
   13208           4 :         TALLOC_FREE(mangled_name);
   13209           4 :         TALLOC_FREE(windows_rename_src);
   13210             : 
   13211           4 :         if (cli != NULL) {
   13212           4 :                 torture_deltree(cli, dname);
   13213           4 :                 torture_close_connection(cli);
   13214             :         }
   13215             : 
   13216           4 :         torture_close_connection(cli_posix);
   13217             : 
   13218           4 :         return correct;
   13219             : }
   13220             : 
   13221             : /*
   13222             :  * Only testing minimal time strings, as the others
   13223             :  * need (locale-dependent) guessing at what strftime does and
   13224             :  * even may differ in builds.
   13225             :  */
   13226           1 : static bool timesubst_test(void)
   13227             : {
   13228           1 :         TALLOC_CTX *ctx = NULL;
   13229             :         /* Sa 23. Dez 04:33:20 CET 2017 */
   13230           1 :         const struct timeval tv = { 1514000000, 123 };
   13231           1 :         const char* expect_minimal = "20171223_033320";
   13232           1 :         const char* expect_minus   = "20171223_033320_000123";
   13233           1 :         char *s;
   13234           1 :         char *env_tz, *orig_tz = NULL;
   13235           1 :         bool result = true;
   13236             : 
   13237           1 :         ctx = talloc_new(NULL);
   13238             : 
   13239           1 :         env_tz = getenv("TZ");
   13240           1 :         if(env_tz) {
   13241           1 :                 orig_tz = talloc_strdup(ctx, env_tz);
   13242             :         }
   13243           1 :         setenv("TZ", "UTC", 1);
   13244             : 
   13245           1 :         s = minimal_timeval_string(ctx, &tv, false);
   13246             : 
   13247           1 :         if(!s || strcmp(s, expect_minimal)) {
   13248           0 :                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
   13249             :                        "[%s]\n", s ? s : "<nil>", expect_minimal);
   13250           0 :                 result = false;
   13251             :         }
   13252           1 :         TALLOC_FREE(s);
   13253           1 :         s = minimal_timeval_string(ctx, &tv, true);
   13254           1 :         if(!s || strcmp(s, expect_minus)) {
   13255           0 :                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
   13256             :                        "[%s]\n", s ? s : "<nil>", expect_minus);
   13257           0 :                 result = false;
   13258             :         }
   13259           1 :         TALLOC_FREE(s);
   13260             : 
   13261           1 :         if(orig_tz) {
   13262           1 :                 setenv("TZ", orig_tz, 1);
   13263             :         }
   13264             : 
   13265           1 :         TALLOC_FREE(ctx);
   13266           1 :         return result;
   13267             : }
   13268             : 
   13269           1 : static bool run_local_substitute(int dummy)
   13270             : {
   13271           1 :         bool ok = true;
   13272             : 
   13273           1 :         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
   13274           1 :         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
   13275           1 :         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
   13276           1 :         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
   13277           1 :         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
   13278           1 :         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
   13279           1 :         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
   13280           1 :         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
   13281           1 :         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
   13282             :         /* Substitution depends on current time, so better test the underlying
   13283             :            formatting function. At least covers %t. */
   13284           1 :         ok &= timesubst_test();
   13285             : 
   13286             :         /* Different captialization rules in sub_basic... */
   13287             : 
   13288           1 :         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
   13289           1 :                        "blaDOM") == 0);
   13290             : 
   13291           1 :         return ok;
   13292             : }
   13293             : 
   13294           1 : static bool run_local_base64(int dummy)
   13295             : {
   13296           1 :         int i;
   13297           1 :         bool ret = true;
   13298             : 
   13299        2000 :         for (i=1; i<2000; i++) {
   13300        1999 :                 DATA_BLOB blob1, blob2;
   13301        1999 :                 char *b64;
   13302             : 
   13303        1999 :                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
   13304        1999 :                 blob1.length = i;
   13305        1999 :                 generate_random_buffer(blob1.data, blob1.length);
   13306             : 
   13307        1999 :                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
   13308        1999 :                 if (b64 == NULL) {
   13309           0 :                         d_fprintf(stderr, "base64_encode_data_blob failed "
   13310             :                                   "for %d bytes\n", i);
   13311           0 :                         ret = false;
   13312             :                 }
   13313        1999 :                 blob2 = base64_decode_data_blob(b64);
   13314        1999 :                 TALLOC_FREE(b64);
   13315             : 
   13316        1999 :                 if (data_blob_cmp(&blob1, &blob2)) {
   13317           0 :                         d_fprintf(stderr, "data_blob_cmp failed for %d "
   13318             :                                   "bytes\n", i);
   13319           0 :                         ret = false;
   13320             :                 }
   13321        1999 :                 TALLOC_FREE(blob1.data);
   13322        1999 :                 data_blob_free(&blob2);
   13323             :         }
   13324           1 :         return ret;
   13325             : }
   13326             : 
   13327     1000000 : static void parse_fn(const struct gencache_timeout *t,
   13328             :                      DATA_BLOB blob,
   13329             :                      void *private_data)
   13330             : {
   13331     1000000 :         return;
   13332             : }
   13333             : 
   13334           1 : static bool run_local_gencache(int dummy)
   13335             : {
   13336           1 :         char *val;
   13337           1 :         time_t tm;
   13338           1 :         DATA_BLOB blob;
   13339           1 :         char v;
   13340           1 :         struct memcache *mem;
   13341           1 :         int i;
   13342             : 
   13343           1 :         mem = memcache_init(NULL, 0);
   13344           1 :         if (mem == NULL) {
   13345           0 :                 d_printf("%s: memcache_init failed\n", __location__);
   13346           0 :                 return false;
   13347             :         }
   13348           1 :         memcache_set_global(mem);
   13349             : 
   13350           1 :         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
   13351           0 :                 d_printf("%s: gencache_set() failed\n", __location__);
   13352           0 :                 return False;
   13353             :         }
   13354             : 
   13355           1 :         if (!gencache_get("foo", NULL, NULL, NULL)) {
   13356           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13357           0 :                 return False;
   13358             :         }
   13359             : 
   13360     1000001 :         for (i=0; i<1000000; i++) {
   13361     1000000 :                 gencache_parse("foo", parse_fn, NULL);
   13362             :         }
   13363             : 
   13364           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13365           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13366           0 :                 return False;
   13367             :         }
   13368           1 :         TALLOC_FREE(val);
   13369             : 
   13370           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13371           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13372           0 :                 return False;
   13373             :         }
   13374             : 
   13375           1 :         if (strcmp(val, "bar") != 0) {
   13376           0 :                 d_printf("%s: gencache_get() returned %s, expected %s\n",
   13377             :                          __location__, val, "bar");
   13378           0 :                 TALLOC_FREE(val);
   13379           0 :                 return False;
   13380             :         }
   13381             : 
   13382           1 :         TALLOC_FREE(val);
   13383             : 
   13384           1 :         if (!gencache_del("foo")) {
   13385           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13386           0 :                 return False;
   13387             :         }
   13388           1 :         if (gencache_del("foo")) {
   13389           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13390             :                          __location__);
   13391           0 :                 return False;
   13392             :         }
   13393             : 
   13394           1 :         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
   13395           0 :                 d_printf("%s: gencache_get() on deleted entry "
   13396             :                          "succeeded\n", __location__);
   13397           0 :                 return False;
   13398             :         }
   13399             : 
   13400           1 :         blob = data_blob_string_const_null("bar");
   13401           1 :         tm = time(NULL) + 60;
   13402             : 
   13403           1 :         if (!gencache_set_data_blob("foo", blob, tm)) {
   13404           0 :                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
   13405           0 :                 return False;
   13406             :         }
   13407             : 
   13408           1 :         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13409           0 :                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
   13410           0 :                 return False;
   13411             :         }
   13412             : 
   13413           1 :         if (strcmp((const char *)blob.data, "bar") != 0) {
   13414           0 :                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
   13415           0 :                          __location__, (const char *)blob.data, "bar");
   13416           0 :                 data_blob_free(&blob);
   13417           0 :                 return False;
   13418             :         }
   13419             : 
   13420           1 :         data_blob_free(&blob);
   13421             : 
   13422           1 :         if (!gencache_del("foo")) {
   13423           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13424           0 :                 return False;
   13425             :         }
   13426           1 :         if (gencache_del("foo")) {
   13427           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13428             :                          __location__);
   13429           0 :                 return False;
   13430             :         }
   13431             : 
   13432           1 :         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13433           0 :                 d_printf("%s: gencache_get_data_blob() on deleted entry "
   13434             :                          "succeeded\n", __location__);
   13435           0 :                 return False;
   13436             :         }
   13437             : 
   13438           1 :         v = 1;
   13439           1 :         blob.data = (uint8_t *)&v;
   13440           1 :         blob.length = sizeof(v);
   13441             : 
   13442           1 :         if (!gencache_set_data_blob("blob", blob, tm)) {
   13443           0 :                 d_printf("%s: gencache_set_data_blob() failed\n",
   13444             :                          __location__);
   13445           0 :                 return false;
   13446             :         }
   13447           1 :         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
   13448           0 :                 d_printf("%s: gencache_get succeeded\n", __location__);
   13449           0 :                 return false;
   13450             :         }
   13451             : 
   13452           0 :         return True;
   13453             : }
   13454             : 
   13455           1 : static bool rbt_testflags(struct db_context *db, const char *key,
   13456             :                           const char *value)
   13457             : {
   13458           1 :         bool ret = false;
   13459           1 :         NTSTATUS status;
   13460           1 :         struct db_record *rec;
   13461             : 
   13462           1 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13463           1 :         if (rec == NULL) {
   13464           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13465           0 :                 goto done;
   13466             :         }
   13467             : 
   13468           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13469           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   13470           0 :                 d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
   13471             :                           nt_errstr(status));
   13472           0 :                 goto done;
   13473             :         }
   13474             : 
   13475           1 :         status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
   13476             :                                      TDB_INSERT);
   13477           1 :         if (!NT_STATUS_IS_OK(status)) {
   13478           0 :                 d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
   13479             :                           nt_errstr(status));
   13480           0 :                 goto done;
   13481             :         }
   13482             : 
   13483           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
   13484           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
   13485           0 :                 d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
   13486             :                           nt_errstr(status));
   13487           0 :                 goto done;
   13488             :         }
   13489             : 
   13490           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13491           1 :         if (!NT_STATUS_IS_OK(status)) {
   13492           0 :                 d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
   13493             :                           nt_errstr(status));
   13494           0 :                 goto done;
   13495             :         }
   13496             : 
   13497           0 :         ret = true;
   13498           1 : done:
   13499           1 :         TALLOC_FREE(rec);
   13500           1 :         return ret;
   13501             : }
   13502             : 
   13503        1998 : static bool rbt_testval(struct db_context *db, const char *key,
   13504             :                         const char *value)
   13505             : {
   13506        1998 :         struct db_record *rec;
   13507        1998 :         TDB_DATA data = string_tdb_data(value);
   13508        1998 :         bool ret = false;
   13509        1998 :         NTSTATUS status;
   13510        1998 :         TDB_DATA dbvalue;
   13511             : 
   13512        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13513        1998 :         if (rec == NULL) {
   13514           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13515           0 :                 goto done;
   13516             :         }
   13517        1998 :         status = dbwrap_record_store(rec, data, 0);
   13518        1998 :         if (!NT_STATUS_IS_OK(status)) {
   13519           0 :                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
   13520           0 :                 goto done;
   13521             :         }
   13522        1998 :         TALLOC_FREE(rec);
   13523             : 
   13524        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13525        1998 :         if (rec == NULL) {
   13526           0 :                 d_fprintf(stderr, "second fetch_locked failed\n");
   13527           0 :                 goto done;
   13528             :         }
   13529             : 
   13530        1998 :         dbvalue = dbwrap_record_get_value(rec);
   13531        1998 :         if ((dbvalue.dsize != data.dsize)
   13532        1998 :             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
   13533           0 :                 d_fprintf(stderr, "Got wrong data back\n");
   13534           0 :                 goto done;
   13535             :         }
   13536             : 
   13537           0 :         ret = true;
   13538        1998 :  done:
   13539        1998 :         TALLOC_FREE(rec);
   13540        1998 :         return ret;
   13541             : }
   13542             : 
   13543        1000 : static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
   13544             : {
   13545        1000 :         int *count2 = (int *)private_data;
   13546        1000 :         (*count2)++;
   13547        1000 :         return 0;
   13548             : }
   13549             : 
   13550        1000 : static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
   13551             : {
   13552        1000 :         int *count2 = (int *)private_data;
   13553        1000 :         (*count2)++;
   13554        1000 :         dbwrap_record_delete(rec);
   13555        1000 :         return 0;
   13556             : }
   13557             : 
   13558           1 : static bool run_local_rbtree(int dummy)
   13559             : {
   13560           1 :         struct db_context *db;
   13561           1 :         bool ret = false;
   13562           1 :         int i;
   13563           1 :         NTSTATUS status;
   13564           1 :         int count = 0;
   13565           1 :         int count2 = 0;
   13566             : 
   13567           1 :         db = db_open_rbt(NULL);
   13568             : 
   13569           1 :         if (db == NULL) {
   13570           0 :                 d_fprintf(stderr, "db_open_rbt failed\n");
   13571           0 :                 return false;
   13572             :         }
   13573             : 
   13574           1 :         if (!rbt_testflags(db, "firstkey", "firstval")) {
   13575           0 :                 goto done;
   13576             :         }
   13577             : 
   13578        1000 :         for (i = 0; i < 999; i++) {
   13579         999 :                 char key[sizeof("key-9223372036854775807")];
   13580         999 :                 char value[sizeof("value-9223372036854775807")];
   13581             : 
   13582         999 :                 snprintf(key, sizeof(key), "key%ld", random());
   13583         999 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13584             : 
   13585         999 :                 if (!rbt_testval(db, key, value)) {
   13586           0 :                         goto done;
   13587             :                 }
   13588             : 
   13589         999 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13590             : 
   13591         999 :                 if (!rbt_testval(db, key, value)) {
   13592           0 :                         goto done;
   13593             :                 }
   13594             :         }
   13595             : 
   13596           1 :         ret = true;
   13597           1 :         count = 0; count2 = 0;
   13598           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13599             :                                       &count2, &count);
   13600           1 :         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13601           1 :         if ((count != count2) || (count != 1000)) {
   13602           0 :                 ret = false;
   13603             :         }
   13604           1 :         count = 0; count2 = 0;
   13605           1 :         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
   13606             :                                  &count2, &count);
   13607           1 :         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13608           1 :         if ((count != count2) || (count != 1000)) {
   13609           0 :                 ret = false;
   13610             :         }
   13611           1 :         count = 0; count2 = 0;
   13612           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13613             :                                       &count2, &count);
   13614           1 :         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13615           1 :         if ((count != count2) || (count != 0)) {
   13616           0 :                 ret = false;
   13617             :         }
   13618             : 
   13619           1 :  done:
   13620           1 :         TALLOC_FREE(db);
   13621           1 :         return ret;
   13622             : }
   13623             : 
   13624             : 
   13625             : /*
   13626             :   local test for character set functions
   13627             : 
   13628             :   This is a very simple test for the functionality in convert_string_error()
   13629             :  */
   13630           1 : static bool run_local_convert_string(int dummy)
   13631             : {
   13632           1 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   13633           1 :         const char *test_strings[2] = { "March", "M\303\244rz" };
   13634           1 :         char dst[7];
   13635           1 :         int i;
   13636             : 
   13637           3 :         for (i=0; i<2; i++) {
   13638           2 :                 const char *str = test_strings[i];
   13639           2 :                 int len = strlen(str);
   13640           2 :                 size_t converted_size;
   13641           2 :                 bool ret;
   13642             : 
   13643           2 :                 memset(dst, 'X', sizeof(dst));
   13644             : 
   13645             :                 /* first try with real source length */
   13646           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13647             :                                            str, len,
   13648             :                                            dst, sizeof(dst),
   13649             :                                            &converted_size);
   13650           2 :                 if (ret != true) {
   13651           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13652           0 :                         goto failed;
   13653             :                 }
   13654             : 
   13655           2 :                 if (converted_size != len) {
   13656           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13657             :                                   str, len, (int)converted_size);
   13658           0 :                         goto failed;
   13659             :                 }
   13660             : 
   13661           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13662           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13663           0 :                         goto failed;
   13664             :                 }
   13665             : 
   13666           2 :                 if (strlen(str) != converted_size) {
   13667           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13668           0 :                                   (int)strlen(str), (int)converted_size);
   13669           0 :                         goto failed;
   13670             :                 }
   13671             : 
   13672           2 :                 if (dst[converted_size] != 'X') {
   13673           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13674           0 :                         goto failed;
   13675             :                 }
   13676             : 
   13677             :                 /* now with srclen==-1, this causes the nul to be
   13678             :                  * converted too */
   13679           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13680             :                                            str, -1,
   13681             :                                            dst, sizeof(dst),
   13682             :                                            &converted_size);
   13683           2 :                 if (ret != true) {
   13684           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13685           0 :                         goto failed;
   13686             :                 }
   13687             : 
   13688           2 :                 if (converted_size != len+1) {
   13689           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13690             :                                   str, len, (int)converted_size);
   13691           0 :                         goto failed;
   13692             :                 }
   13693             : 
   13694           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13695           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13696           0 :                         goto failed;
   13697             :                 }
   13698             : 
   13699           2 :                 if (len+1 != converted_size) {
   13700           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13701             :                                   len+1, (int)converted_size);
   13702           0 :                         goto failed;
   13703             :                 }
   13704             : 
   13705           2 :                 if (dst[converted_size] != 'X') {
   13706           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13707           0 :                         goto failed;
   13708             :                 }
   13709             : 
   13710             :         }
   13711             : 
   13712             : 
   13713           1 :         TALLOC_FREE(tmp_ctx);
   13714           0 :         return true;
   13715           0 : failed:
   13716           0 :         TALLOC_FREE(tmp_ctx);
   13717           0 :         return false;
   13718             : }
   13719             : 
   13720           1 : static bool run_local_string_to_sid(int dummy) {
   13721           1 :         struct dom_sid sid;
   13722             : 
   13723           1 :         if (string_to_sid(&sid, "S--1-5-32-545")) {
   13724           0 :                 printf("allowing S--1-5-32-545\n");
   13725           0 :                 return false;
   13726             :         }
   13727           1 :         if (string_to_sid(&sid, "S-1-5-32-+545")) {
   13728           0 :                 printf("allowing S-1-5-32-+545\n");
   13729           0 :                 return false;
   13730             :         }
   13731           1 :         if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
   13732           0 :                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
   13733           0 :                 return false;
   13734             :         }
   13735           1 :         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
   13736           0 :                 printf("allowing S-1-5-32-545-abc\n");
   13737           0 :                 return false;
   13738             :         }
   13739           1 :         if (string_to_sid(&sid, "S-300-5-32-545")) {
   13740           0 :                 printf("allowing S-300-5-32-545\n");
   13741           0 :                 return false;
   13742             :         }
   13743           1 :         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
   13744           0 :                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
   13745           0 :                 return false;
   13746             :         }
   13747           1 :         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
   13748           0 :                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
   13749           0 :                 return false;
   13750             :         }
   13751           1 :         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
   13752           0 :                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
   13753           0 :                 return false;
   13754             :         }
   13755           1 :         if (!string_to_sid(&sid, "S-1-5-32-545")) {
   13756           0 :                 printf("could not parse S-1-5-32-545\n");
   13757           0 :                 return false;
   13758             :         }
   13759           1 :         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
   13760           0 :                 struct dom_sid_buf buf;
   13761           0 :                 printf("mis-parsed S-1-5-32-545 as %s\n",
   13762             :                        dom_sid_str_buf(&sid, &buf));
   13763           0 :                 return false;
   13764             :         }
   13765           0 :         return true;
   13766             : }
   13767             : 
   13768           3 : static bool sid_to_string_test(const char *expected) {
   13769           3 :         char *str;
   13770           3 :         bool res = true;
   13771           3 :         struct dom_sid sid;
   13772             : 
   13773           3 :         if (!string_to_sid(&sid, expected)) {
   13774           0 :                 printf("could not parse %s\n", expected);
   13775           0 :                 return false;
   13776             :         }
   13777             : 
   13778           3 :         str = dom_sid_string(NULL, &sid);
   13779           3 :         if (strcmp(str, expected)) {
   13780           0 :                 printf("Comparison failed (%s != %s)\n", str, expected);
   13781           0 :                 res = false;
   13782             :         }
   13783           3 :         TALLOC_FREE(str);
   13784           3 :         return res;
   13785             : }
   13786             : 
   13787           1 : static bool run_local_sid_to_string(int dummy) {
   13788           1 :         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
   13789           0 :                 return false;
   13790           1 :         if (!sid_to_string_test("S-1-545"))
   13791           0 :                 return false;
   13792           1 :         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
   13793           0 :                 return false;
   13794           0 :         return true;
   13795             : }
   13796             : 
   13797           1 : static bool run_local_binary_to_sid(int dummy) {
   13798           1 :         ssize_t ret;
   13799           1 :         struct dom_sid *sid = talloc(NULL, struct dom_sid);
   13800           1 :         static const uint8_t good_binary_sid[] = {
   13801             :                 0x1, /* revision number */
   13802             :                 15, /* num auths */
   13803             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13804             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13805             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13806             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13807             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13808             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13809             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13810             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13811             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13812             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13813             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13814             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13815             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13816             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13817             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13818             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13819             :         };
   13820             : 
   13821           1 :         static const uint8_t long_binary_sid[] = {
   13822             :                 0x1, /* revision number */
   13823             :                 15, /* num auths */
   13824             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13825             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13826             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13827             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13828             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13829             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13830             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13831             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13832             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13833             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13834             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13835             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13836             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13837             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13838             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13839             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13840             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13841             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13842             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13843             :         };
   13844             : 
   13845           1 :         static const uint8_t long_binary_sid2[] = {
   13846             :                 0x1, /* revision number */
   13847             :                 32, /* num auths */
   13848             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13849             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13850             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13851             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13852             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13853             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13854             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13855             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13856             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13857             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13858             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13859             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13860             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13861             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13862             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13863             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13864             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13865             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13866             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13867             :                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
   13868             :                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
   13869             :                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
   13870             :                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
   13871             :                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
   13872             :                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
   13873             :                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
   13874             :                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
   13875             :                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
   13876             :                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
   13877             :                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
   13878             :                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
   13879             :                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
   13880             :                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
   13881             :         };
   13882             : 
   13883           1 :         ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
   13884           1 :         if (ret == -1) {
   13885           0 :                 return false;
   13886             :         }
   13887           1 :         ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
   13888           1 :         if (ret != -1) {
   13889           0 :                 return false;
   13890             :         }
   13891           1 :         ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
   13892           1 :         if (ret != -1) {
   13893           0 :                 return false;
   13894             :         }
   13895           0 :         return true;
   13896             : }
   13897             : 
   13898             : /* Split a path name into filename and stream name components. Canonicalise
   13899             :  * such that an implicit $DATA token is always explicit.
   13900             :  *
   13901             :  * The "specification" of this function can be found in the
   13902             :  * run_local_stream_name() function in torture.c, I've tried those
   13903             :  * combinations against a W2k3 server.
   13904             :  */
   13905             : 
   13906           8 : static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
   13907             :                                        char **pbase, char **pstream)
   13908             : {
   13909           8 :         char *base = NULL;
   13910           8 :         char *stream = NULL;
   13911           8 :         char *sname; /* stream name */
   13912           8 :         const char *stype; /* stream type */
   13913             : 
   13914           8 :         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
   13915             : 
   13916           8 :         sname = strchr_m(fname, ':');
   13917             : 
   13918           8 :         if (sname == NULL) {
   13919           1 :                 if (pbase != NULL) {
   13920           1 :                         base = talloc_strdup(mem_ctx, fname);
   13921           1 :                         NT_STATUS_HAVE_NO_MEMORY(base);
   13922             :                 }
   13923           1 :                 goto done;
   13924             :         }
   13925             : 
   13926           7 :         if (pbase != NULL) {
   13927           7 :                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
   13928           7 :                 NT_STATUS_HAVE_NO_MEMORY(base);
   13929             :         }
   13930             : 
   13931           7 :         sname += 1;
   13932             : 
   13933           7 :         stype = strchr_m(sname, ':');
   13934             : 
   13935           7 :         if (stype == NULL) {
   13936           2 :                 sname = talloc_strdup(mem_ctx, sname);
   13937           2 :                 stype = "$DATA";
   13938             :         }
   13939             :         else {
   13940           5 :                 if (strcasecmp_m(stype, ":$DATA") != 0) {
   13941             :                         /*
   13942             :                          * If there is an explicit stream type, so far we only
   13943             :                          * allow $DATA. Is there anything else allowed? -- vl
   13944             :                          */
   13945           3 :                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
   13946           3 :                         TALLOC_FREE(base);
   13947           3 :                         return NT_STATUS_OBJECT_NAME_INVALID;
   13948             :                 }
   13949           2 :                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
   13950           2 :                 stype += 1;
   13951             :         }
   13952             : 
   13953           4 :         if (sname == NULL) {
   13954           0 :                 TALLOC_FREE(base);
   13955           0 :                 return NT_STATUS_NO_MEMORY;
   13956             :         }
   13957             : 
   13958           4 :         if (sname[0] == '\0') {
   13959             :                 /*
   13960             :                  * no stream name, so no stream
   13961             :                  */
   13962           1 :                 goto done;
   13963             :         }
   13964             : 
   13965           3 :         if (pstream != NULL) {
   13966           3 :                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
   13967           3 :                 if (stream == NULL) {
   13968           0 :                         TALLOC_FREE(sname);
   13969           0 :                         TALLOC_FREE(base);
   13970           0 :                         return NT_STATUS_NO_MEMORY;
   13971             :                 }
   13972             :                 /*
   13973             :                  * upper-case the type field
   13974             :                  */
   13975           3 :                 (void)strupper_m(strchr_m(stream, ':')+1);
   13976             :         }
   13977             : 
   13978           0 :  done:
   13979           5 :         if (pbase != NULL) {
   13980           5 :                 *pbase = base;
   13981             :         }
   13982           5 :         if (pstream != NULL) {
   13983           5 :                 *pstream = stream;
   13984             :         }
   13985           5 :         return NT_STATUS_OK;
   13986             : }
   13987             : 
   13988           8 : static bool test_stream_name(const char *fname, const char *expected_base,
   13989             :                              const char *expected_stream,
   13990             :                              NTSTATUS expected_status)
   13991             : {
   13992           8 :         NTSTATUS status;
   13993           8 :         char *base = NULL;
   13994           8 :         char *stream = NULL;
   13995             : 
   13996           8 :         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
   13997           8 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   13998           0 :                 goto error;
   13999             :         }
   14000             : 
   14001           8 :         if (!NT_STATUS_IS_OK(status)) {
   14002           0 :                 return true;
   14003             :         }
   14004             : 
   14005           5 :         if (base == NULL) goto error;
   14006             : 
   14007           5 :         if (strcmp(expected_base, base) != 0) goto error;
   14008             : 
   14009           5 :         if ((expected_stream != NULL) && (stream == NULL)) goto error;
   14010           5 :         if ((expected_stream == NULL) && (stream != NULL)) goto error;
   14011             : 
   14012           5 :         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
   14013           0 :                 goto error;
   14014             : 
   14015           5 :         TALLOC_FREE(base);
   14016           5 :         TALLOC_FREE(stream);
   14017           0 :         return true;
   14018             : 
   14019           0 :  error:
   14020           0 :         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
   14021             :                   fname, expected_base ? expected_base : "<NULL>",
   14022             :                   expected_stream ? expected_stream : "<NULL>",
   14023             :                   nt_errstr(expected_status));
   14024           0 :         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
   14025           0 :                   base ? base : "<NULL>", stream ? stream : "<NULL>",
   14026             :                   nt_errstr(status));
   14027           0 :         TALLOC_FREE(base);
   14028           0 :         TALLOC_FREE(stream);
   14029           0 :         return false;
   14030             : }
   14031             : 
   14032           1 : static bool run_local_stream_name(int dummy)
   14033             : {
   14034           1 :         bool ret = true;
   14035             : 
   14036           2 :         ret &= test_stream_name(
   14037           1 :                 "bla", "bla", NULL, NT_STATUS_OK);
   14038           2 :         ret &= test_stream_name(
   14039           1 :                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
   14040           2 :         ret &= test_stream_name(
   14041           1 :                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14042           2 :         ret &= test_stream_name(
   14043           1 :                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14044           2 :         ret &= test_stream_name(
   14045           1 :                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14046           2 :         ret &= test_stream_name(
   14047           1 :                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
   14048           2 :         ret &= test_stream_name(
   14049           1 :                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
   14050           2 :         ret &= test_stream_name(
   14051           1 :                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
   14052             : 
   14053           1 :         return ret;
   14054             : }
   14055             : 
   14056           2 : static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
   14057             : {
   14058           2 :         if (a.length != b.length) {
   14059           0 :                 printf("a.length=%d != b.length=%d\n",
   14060           0 :                        (int)a.length, (int)b.length);
   14061           0 :                 return false;
   14062             :         }
   14063           2 :         if (memcmp(a.data, b.data, a.length) != 0) {
   14064           0 :                 printf("a.data and b.data differ\n");
   14065           0 :                 return false;
   14066             :         }
   14067           0 :         return true;
   14068             : }
   14069             : 
   14070           1 : static bool run_local_memcache(int dummy)
   14071             : {
   14072           1 :         struct memcache *cache;
   14073           1 :         DATA_BLOB k1, k2, k3, k4, k5;
   14074           1 :         DATA_BLOB d1, d3;
   14075           1 :         DATA_BLOB v1, v3;
   14076             : 
   14077           1 :         TALLOC_CTX *mem_ctx;
   14078           1 :         char *ptr1 = NULL;
   14079           1 :         char *ptr2 = NULL;
   14080           1 :         char *ptr3 = NULL;
   14081             : 
   14082           1 :         char *str1, *str2;
   14083           1 :         size_t size1, size2;
   14084           1 :         bool ret = false;
   14085             : 
   14086           1 :         mem_ctx = talloc_init("foo");
   14087           1 :         if (mem_ctx == NULL) {
   14088           0 :                 return false;
   14089             :         }
   14090             : 
   14091             :         /* STAT_CACHE TESTS */
   14092             : 
   14093           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14094             : 
   14095           1 :         if (cache == NULL) {
   14096           0 :                 printf("memcache_init failed\n");
   14097           0 :                 return false;
   14098             :         }
   14099             : 
   14100           1 :         d1 = data_blob_const("d1", 2);
   14101           1 :         d3 = data_blob_const("d3", 2);
   14102             : 
   14103           1 :         k1 = data_blob_const("d1", 2);
   14104           1 :         k2 = data_blob_const("d2", 2);
   14105           1 :         k3 = data_blob_const("d3", 2);
   14106           1 :         k4 = data_blob_const("d4", 2);
   14107           1 :         k5 = data_blob_const("d5", 2);
   14108             : 
   14109           1 :         memcache_add(cache, STAT_CACHE, k1, d1);
   14110             : 
   14111           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
   14112           0 :                 printf("could not find k1\n");
   14113           0 :                 return false;
   14114             :         }
   14115           1 :         if (!data_blob_equal(d1, v1)) {
   14116           0 :                 return false;
   14117             :         }
   14118             : 
   14119           1 :         memcache_add(cache, STAT_CACHE, k1, d3);
   14120             : 
   14121           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
   14122           0 :                 printf("could not find replaced k1\n");
   14123           0 :                 return false;
   14124             :         }
   14125           1 :         if (!data_blob_equal(d3, v3)) {
   14126           0 :                 return false;
   14127             :         }
   14128             : 
   14129           1 :         TALLOC_FREE(cache);
   14130             : 
   14131             :         /* GETWD_CACHE TESTS */
   14132           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14133           1 :         if (str1 == NULL) {
   14134           0 :                 return false;
   14135             :         }
   14136           1 :         ptr2 = str1; /* Keep an alias for comparison. */
   14137             : 
   14138           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14139           1 :         if (str2 == NULL) {
   14140           0 :                 return false;
   14141             :         }
   14142             : 
   14143           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14144           1 :         if (cache == NULL) {
   14145           0 :                 printf("memcache_init failed\n");
   14146           0 :                 return false;
   14147             :         }
   14148             : 
   14149           1 :         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
   14150             :         /* str1 == NULL now. */
   14151           1 :         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14152           1 :         if (ptr1 == NULL) {
   14153           0 :                 printf("could not find k2\n");
   14154           0 :                 return false;
   14155             :         }
   14156           1 :         if (ptr1 != ptr2) {
   14157           0 :                 printf("fetch of k2 got wrong string\n");
   14158           0 :                 return false;
   14159             :         }
   14160             : 
   14161             :         /* Add a blob to ensure k2 gets purged. */
   14162           1 :         d3 = data_blob_talloc_zero(mem_ctx, 180);
   14163           1 :         memcache_add(cache, STAT_CACHE, k3, d3);
   14164             : 
   14165           1 :         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14166           1 :         if (ptr2 != NULL) {
   14167           0 :                 printf("Did find k2, should have been purged\n");
   14168           0 :                 return false;
   14169             :         }
   14170             : 
   14171             :         /*
   14172             :          * Test that talloc size also is accounted in memcache and
   14173             :          * causes purge of other object.
   14174             :          */
   14175             : 
   14176           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14177           1 :         str2 = talloc_zero_size(mem_ctx, 100);
   14178             : 
   14179           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14180           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
   14181             : 
   14182           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14183           1 :         if (ptr3 != NULL) {
   14184           0 :                 printf("Did find k4, should have been purged\n");
   14185           0 :                 return false;
   14186             :         }
   14187             : 
   14188             :         /*
   14189             :          * Test that adding a duplicate non-talloced
   14190             :          * key/value on top of a talloced key/value takes account
   14191             :          * of the talloc_freed value size.
   14192             :          */
   14193           1 :         TALLOC_FREE(cache);
   14194           1 :         TALLOC_FREE(mem_ctx);
   14195             : 
   14196           1 :         mem_ctx = talloc_init("key_replace");
   14197           1 :         if (mem_ctx == NULL) {
   14198           0 :                 return false;
   14199             :         }
   14200             : 
   14201           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14202           1 :         if (cache == NULL) {
   14203           0 :                 return false;
   14204             :         }
   14205             : 
   14206             :         /*
   14207             :          * Add a 100 byte talloced string. This will
   14208             :          * store a (4 or 8 byte) pointer and record the
   14209             :          * total talloced size.
   14210             :          */
   14211           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14212           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14213             :         /*
   14214             :          * Now overwrite with a small talloced
   14215             :          * value. This should fit in the existing size
   14216             :          * and the total talloced size should be removed
   14217             :          * from the cache size.
   14218             :          */
   14219           1 :         str1 = talloc_zero_size(mem_ctx, 2);
   14220           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14221             :         /*
   14222             :          * Now store a 20 byte string. If the
   14223             :          * total talloced size wasn't accounted for
   14224             :          * and removed in the overwrite, then this
   14225             :          * will evict k4.
   14226             :          */
   14227           1 :         str2 = talloc_zero_size(mem_ctx, 20);
   14228           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
   14229             : 
   14230           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14231           1 :         if (ptr3 == NULL) {
   14232           0 :                 printf("Did not find k4, should not have been purged\n");
   14233           0 :                 return false;
   14234             :         }
   14235             : 
   14236           1 :         TALLOC_FREE(cache);
   14237           1 :         TALLOC_FREE(mem_ctx);
   14238             : 
   14239           1 :         mem_ctx = talloc_init("foo");
   14240           1 :         if (mem_ctx == NULL) {
   14241           0 :                 return false;
   14242             :         }
   14243             : 
   14244           1 :         cache = memcache_init(NULL, 0);
   14245           1 :         if (cache == NULL) {
   14246           0 :                 return false;
   14247             :         }
   14248             : 
   14249           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14250           1 :         if (str1 == NULL) {
   14251           0 :                 return false;
   14252             :         }
   14253           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14254           1 :         if (str2 == NULL) {
   14255           0 :                 return false;
   14256             :         }
   14257           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14258             :                             data_blob_string_const("torture"), &str1);
   14259           1 :         size1 = talloc_total_size(cache);
   14260             : 
   14261           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14262             :                             data_blob_string_const("torture"), &str2);
   14263           1 :         size2 = talloc_total_size(cache);
   14264             : 
   14265           1 :         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
   14266             : 
   14267           1 :         if (size2 > size1) {
   14268           0 :                 printf("memcache leaks memory!\n");
   14269           0 :                 goto fail;
   14270             :         }
   14271             : 
   14272           0 :         ret = true;
   14273           1 :  fail:
   14274           1 :         TALLOC_FREE(cache);
   14275           1 :         return ret;
   14276             : }
   14277             : 
   14278         200 : static void wbclient_done(struct tevent_req *req)
   14279             : {
   14280           0 :         wbcErr wbc_err;
   14281           0 :         struct winbindd_response *wb_resp;
   14282         200 :         int *i = (int *)tevent_req_callback_data_void(req);
   14283             : 
   14284         200 :         wbc_err = wb_trans_recv(req, req, &wb_resp);
   14285         200 :         TALLOC_FREE(req);
   14286         200 :         *i += 1;
   14287         200 :         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
   14288         200 : }
   14289             : 
   14290           2 : static bool run_wbclient_multi_ping(int dummy)
   14291             : {
   14292           0 :         struct tevent_context *ev;
   14293           0 :         struct wb_context **wb_ctx;
   14294           0 :         struct winbindd_request wb_req;
   14295           2 :         bool result = false;
   14296           0 :         int i, j;
   14297             : 
   14298           2 :         BlockSignals(True, SIGPIPE);
   14299             : 
   14300           2 :         ev = tevent_context_init(talloc_tos());
   14301           2 :         if (ev == NULL) {
   14302           0 :                 goto fail;
   14303             :         }
   14304             : 
   14305           2 :         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
   14306           2 :         if (wb_ctx == NULL) {
   14307           0 :                 goto fail;
   14308             :         }
   14309             : 
   14310           2 :         ZERO_STRUCT(wb_req);
   14311           2 :         wb_req.cmd = WINBINDD_PING;
   14312             : 
   14313           2 :         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
   14314             : 
   14315           4 :         for (i=0; i<torture_nprocs; i++) {
   14316           2 :                 wb_ctx[i] = wb_context_init(ev, NULL);
   14317           2 :                 if (wb_ctx[i] == NULL) {
   14318           0 :                         goto fail;
   14319             :                 }
   14320         202 :                 for (j=0; j<torture_numops; j++) {
   14321           0 :                         struct tevent_req *req;
   14322         200 :                         req = wb_trans_send(ev, ev, wb_ctx[i],
   14323         200 :                                             (j % 2) == 0, &wb_req);
   14324         200 :                         if (req == NULL) {
   14325           0 :                                 goto fail;
   14326             :                         }
   14327         200 :                         tevent_req_set_callback(req, wbclient_done, &i);
   14328             :                 }
   14329             :         }
   14330             : 
   14331           2 :         i = 0;
   14332             : 
   14333         818 :         while (i < torture_nprocs * torture_numops) {
   14334         816 :                 tevent_loop_once(ev);
   14335             :         }
   14336             : 
   14337           2 :         result = true;
   14338           2 :  fail:
   14339           2 :         TALLOC_FREE(ev);
   14340           2 :         return result;
   14341             : }
   14342             : 
   14343           0 : static bool dbtrans_inc(struct db_context *db)
   14344             : {
   14345           0 :         struct db_record *rec;
   14346           0 :         uint32_t val;
   14347           0 :         bool ret = false;
   14348           0 :         NTSTATUS status;
   14349           0 :         TDB_DATA value;
   14350             : 
   14351           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14352           0 :         if (rec == NULL) {
   14353           0 :                 printf(__location__ "fetch_lock failed\n");
   14354           0 :                 return false;
   14355             :         }
   14356             : 
   14357           0 :         value = dbwrap_record_get_value(rec);
   14358             : 
   14359           0 :         if (value.dsize != sizeof(uint32_t)) {
   14360           0 :                 printf(__location__ "value.dsize = %d\n",
   14361           0 :                        (int)value.dsize);
   14362           0 :                 goto fail;
   14363             :         }
   14364             : 
   14365           0 :         memcpy(&val, value.dptr, sizeof(val));
   14366           0 :         val += 1;
   14367             : 
   14368           0 :         status = dbwrap_record_store(
   14369             :                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
   14370           0 :         if (!NT_STATUS_IS_OK(status)) {
   14371           0 :                 printf(__location__ "store failed: %s\n",
   14372             :                        nt_errstr(status));
   14373           0 :                 goto fail;
   14374             :         }
   14375             : 
   14376           0 :         ret = true;
   14377           0 : fail:
   14378           0 :         TALLOC_FREE(rec);
   14379           0 :         return ret;
   14380             : }
   14381             : 
   14382           0 : static bool run_local_dbtrans(int dummy)
   14383             : {
   14384           0 :         struct db_context *db;
   14385           0 :         struct db_record *rec;
   14386           0 :         NTSTATUS status;
   14387           0 :         uint32_t initial;
   14388           0 :         int res;
   14389           0 :         TDB_DATA value;
   14390             : 
   14391           0 :         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
   14392             :                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
   14393             :                      DBWRAP_FLAG_NONE);
   14394           0 :         if (db == NULL) {
   14395           0 :                 printf("Could not open transtest.db\n");
   14396           0 :                 return false;
   14397             :         }
   14398             : 
   14399           0 :         res = dbwrap_transaction_start(db);
   14400           0 :         if (res != 0) {
   14401           0 :                 printf(__location__ "transaction_start failed\n");
   14402           0 :                 return false;
   14403             :         }
   14404             : 
   14405           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14406           0 :         if (rec == NULL) {
   14407           0 :                 printf(__location__ "fetch_lock failed\n");
   14408           0 :                 return false;
   14409             :         }
   14410             : 
   14411           0 :         value = dbwrap_record_get_value(rec);
   14412             : 
   14413           0 :         if (value.dptr == NULL) {
   14414           0 :                 initial = 0;
   14415           0 :                 status = dbwrap_record_store(
   14416             :                         rec, make_tdb_data((uint8_t *)&initial,
   14417             :                                            sizeof(initial)),
   14418             :                         0);
   14419           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14420           0 :                         printf(__location__ "store returned %s\n",
   14421             :                                nt_errstr(status));
   14422           0 :                         return false;
   14423             :                 }
   14424             :         }
   14425             : 
   14426           0 :         TALLOC_FREE(rec);
   14427             : 
   14428           0 :         res = dbwrap_transaction_commit(db);
   14429           0 :         if (res != 0) {
   14430           0 :                 printf(__location__ "transaction_commit failed\n");
   14431           0 :                 return false;
   14432             :         }
   14433             : 
   14434           0 :         while (true) {
   14435           0 :                 uint32_t val, val2;
   14436           0 :                 int i;
   14437             : 
   14438           0 :                 res = dbwrap_transaction_start(db);
   14439           0 :                 if (res != 0) {
   14440           0 :                         printf(__location__ "transaction_start failed\n");
   14441           0 :                         break;
   14442             :                 }
   14443             : 
   14444           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
   14445           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14446           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14447             :                                nt_errstr(status));
   14448           0 :                         break;
   14449             :                 }
   14450             : 
   14451           0 :                 for (i=0; i<10; i++) {
   14452           0 :                         if (!dbtrans_inc(db)) {
   14453           0 :                                 return false;
   14454             :                         }
   14455             :                 }
   14456             : 
   14457           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
   14458           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14459           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14460             :                                nt_errstr(status));
   14461           0 :                         break;
   14462             :                 }
   14463             : 
   14464           0 :                 if (val2 != val + 10) {
   14465           0 :                         printf(__location__ "val=%d, val2=%d\n",
   14466             :                                (int)val, (int)val2);
   14467           0 :                         break;
   14468             :                 }
   14469             : 
   14470           0 :                 printf("val2=%d\r", val2);
   14471             : 
   14472           0 :                 res = dbwrap_transaction_commit(db);
   14473           0 :                 if (res != 0) {
   14474           0 :                         printf(__location__ "transaction_commit failed\n");
   14475           0 :                         break;
   14476             :                 }
   14477             :         }
   14478             : 
   14479           0 :         TALLOC_FREE(db);
   14480           0 :         return true;
   14481             : }
   14482             : 
   14483             : /*
   14484             :  * Just a dummy test to be run under a debugger. There's no real way
   14485             :  * to inspect the tevent_poll specific function from outside of
   14486             :  * tevent_poll.c.
   14487             :  */
   14488             : 
   14489           1 : static bool run_local_tevent_poll(int dummy)
   14490             : {
   14491           1 :         struct tevent_context *ev;
   14492           1 :         struct tevent_fd *fd1, *fd2;
   14493           1 :         bool result = false;
   14494             : 
   14495           1 :         ev = tevent_context_init_byname(NULL, "poll");
   14496           1 :         if (ev == NULL) {
   14497           0 :                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
   14498           0 :                 goto fail;
   14499             :         }
   14500             : 
   14501           1 :         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
   14502           1 :         if (fd1 == NULL) {
   14503           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14504           0 :                 goto fail;
   14505             :         }
   14506           1 :         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
   14507           1 :         if (fd2 == NULL) {
   14508           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14509           0 :                 goto fail;
   14510             :         }
   14511           1 :         TALLOC_FREE(fd2);
   14512             : 
   14513           1 :         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
   14514           1 :         if (fd2 == NULL) {
   14515           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14516           0 :                 goto fail;
   14517             :         }
   14518             : 
   14519           0 :         result = true;
   14520           1 : fail:
   14521           1 :         TALLOC_FREE(ev);
   14522           1 :         return result;
   14523             : }
   14524             : 
   14525           1 : static bool run_local_hex_encode_buf(int dummy)
   14526             : {
   14527           1 :         char buf[17];
   14528           1 :         uint8_t src[8];
   14529           1 :         size_t i;
   14530             : 
   14531           9 :         for (i=0; i<sizeof(src); i++) {
   14532           8 :                 src[i] = i;
   14533             :         }
   14534           1 :         hex_encode_buf(buf, src, sizeof(src));
   14535           1 :         if (strcmp(buf, "0001020304050607") != 0) {
   14536           0 :                 return false;
   14537             :         }
   14538           1 :         hex_encode_buf(buf, NULL, 0);
   14539           1 :         if (buf[0] != '\0') {
   14540           0 :                 return false;
   14541             :         }
   14542           0 :         return true;
   14543             : }
   14544             : 
   14545             : static const char *remove_duplicate_addrs2_test_strings_vector[] = {
   14546             :         "0.0.0.0",
   14547             :         "::0",
   14548             :         "1.2.3.1",
   14549             :         "0.0.0.0",
   14550             :         "0.0.0.0",
   14551             :         "1.2.3.2",
   14552             :         "1.2.3.3",
   14553             :         "1.2.3.4",
   14554             :         "1.2.3.5",
   14555             :         "::0",
   14556             :         "1.2.3.6",
   14557             :         "1.2.3.7",
   14558             :         "::0",
   14559             :         "::0",
   14560             :         "::0",
   14561             :         "1.2.3.8",
   14562             :         "1.2.3.9",
   14563             :         "1.2.3.10",
   14564             :         "1.2.3.11",
   14565             :         "1.2.3.12",
   14566             :         "1.2.3.13",
   14567             :         "1001:1111:1111:1000:0:1111:1111:1111",
   14568             :         "1.2.3.1",
   14569             :         "1.2.3.2",
   14570             :         "1.2.3.3",
   14571             :         "1.2.3.12",
   14572             :         "::0",
   14573             :         "::0"
   14574             : };
   14575             : 
   14576             : static const char *remove_duplicate_addrs2_test_strings_result[] = {
   14577             :         "1.2.3.1",
   14578             :         "1.2.3.2",
   14579             :         "1.2.3.3",
   14580             :         "1.2.3.4",
   14581             :         "1.2.3.5",
   14582             :         "1.2.3.6",
   14583             :         "1.2.3.7",
   14584             :         "1.2.3.8",
   14585             :         "1.2.3.9",
   14586             :         "1.2.3.10",
   14587             :         "1.2.3.11",
   14588             :         "1.2.3.12",
   14589             :         "1.2.3.13",
   14590             :         "1001:1111:1111:1000:0:1111:1111:1111"
   14591             : };
   14592             : 
   14593           1 : static bool run_local_remove_duplicate_addrs2(int dummy)
   14594             : {
   14595           1 :         struct samba_sockaddr test_vector[28];
   14596           1 :         size_t count, i;
   14597             : 
   14598             :         /* Construct the sockaddr_storage test vector. */
   14599          29 :         for (i = 0; i < 28; i++) {
   14600          28 :                 struct addrinfo hints;
   14601          28 :                 struct addrinfo *res = NULL;
   14602          28 :                 int ret;
   14603             : 
   14604          28 :                 memset(&hints, '\0', sizeof(hints));
   14605          28 :                 hints.ai_flags = AI_NUMERICHOST;
   14606          28 :                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
   14607             :                                 NULL,
   14608             :                                 &hints,
   14609             :                                 &res);
   14610          28 :                 if (ret) {
   14611           0 :                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
   14612             :                                 remove_duplicate_addrs2_test_strings_vector[i]);
   14613           0 :                         return false;
   14614             :                 }
   14615          28 :                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
   14616          28 :                 memcpy(&test_vector[i].u.ss,
   14617          28 :                         res->ai_addr,
   14618          28 :                         res->ai_addrlen);
   14619          28 :                 freeaddrinfo(res);
   14620             :         }
   14621             : 
   14622           1 :         count = remove_duplicate_addrs2(test_vector, i);
   14623             : 
   14624           1 :         if (count != 14) {
   14625           0 :                 fprintf(stderr, "count wrong (%zu) should be 14\n",
   14626             :                         count);
   14627           0 :                 return false;
   14628             :         }
   14629             : 
   14630          15 :         for (i = 0; i < count; i++) {
   14631          14 :                 char addr[INET6_ADDRSTRLEN];
   14632             : 
   14633          14 :                 print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
   14634             : 
   14635          14 :                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
   14636           0 :                         fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
   14637             :                                 i,
   14638             :                                 addr,
   14639             :                                 remove_duplicate_addrs2_test_strings_result[i]);
   14640           0 :                         return false;
   14641             :                 }
   14642             :         }
   14643             : 
   14644           1 :         printf("run_local_remove_duplicate_addrs2: success\n");
   14645           1 :         return true;
   14646             : }
   14647             : 
   14648           0 : static bool run_local_tdb_opener(int dummy)
   14649             : {
   14650           0 :         TDB_CONTEXT *t;
   14651           0 :         unsigned v = 0;
   14652             : 
   14653           0 :         while (1) {
   14654           0 :                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
   14655             :                              O_RDWR|O_CREAT, 0755);
   14656           0 :                 if (t == NULL) {
   14657           0 :                         perror("tdb_open failed");
   14658           0 :                         return false;
   14659             :                 }
   14660           0 :                 tdb_close(t);
   14661             : 
   14662           0 :                 v += 1;
   14663           0 :                 printf("\r%u", v);
   14664             :         }
   14665             :         return true;
   14666             : }
   14667             : 
   14668           0 : static bool run_local_tdb_writer(int dummy)
   14669             : {
   14670           0 :         TDB_CONTEXT *t;
   14671           0 :         unsigned v = 0;
   14672           0 :         TDB_DATA val;
   14673             : 
   14674           0 :         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
   14675           0 :         if (t == 0) {
   14676           0 :                 perror("tdb_open failed");
   14677           0 :                 return 1;
   14678             :         }
   14679             : 
   14680           0 :         val.dptr = (uint8_t *)&v;
   14681           0 :         val.dsize = sizeof(v);
   14682             : 
   14683           0 :         while (1) {
   14684           0 :                 TDB_DATA data;
   14685           0 :                 int ret;
   14686             : 
   14687           0 :                 ret = tdb_store(t, val, val, 0);
   14688           0 :                 if (ret != 0) {
   14689           0 :                         printf("%s\n", tdb_errorstr(t));
   14690             :                 }
   14691           0 :                 v += 1;
   14692           0 :                 printf("\r%u", v);
   14693             : 
   14694           0 :                 data = tdb_fetch(t, val);
   14695           0 :                 if (data.dptr != NULL) {
   14696           0 :                         SAFE_FREE(data.dptr);
   14697             :                 }
   14698             :         }
   14699             :         return true;
   14700             : }
   14701             : 
   14702           1 : static bool run_local_canonicalize_path(int dummy)
   14703             : {
   14704           1 :         const char *src[] = {
   14705             :                         "/foo/..",
   14706             :                         "/..",
   14707             :                         "/foo/bar/../baz",
   14708             :                         "/foo/././",
   14709             :                         "/../foo",
   14710             :                         ".././././",
   14711             :                         ".././././../../../boo",
   14712             :                         "./..",
   14713             :                         "/",
   14714             :                         "/../../",
   14715             :                         "/foo/../",
   14716             :                         "/./././",
   14717             :                         "/./././.",
   14718             :                         "/.../././.",
   14719             :                         "/./././.foo",
   14720             :                         "/./././.foo.",
   14721             :                         "/./././foo.",
   14722             :                         "/foo/bar/..",
   14723             :                         "/foo/bar/../baz/",
   14724             :                         "////////////////",
   14725             :                         "/////////./././././.",
   14726             :                         "/./.././../.boo/../baz",
   14727             :                         "/a/component/path",
   14728             :                         "/a/component/path/",
   14729             :                         "/a/component/path/..",
   14730             :                         "/a/component/../path/",
   14731             :                         "///a/./././///component/../////path/",
   14732             :                         NULL
   14733             :                         };
   14734           1 :         const char *dst[] = {
   14735             :                         "/",
   14736             :                         "/",
   14737             :                         "/foo/baz",
   14738             :                         "/foo",
   14739             :                         "/foo",
   14740             :                         "/",
   14741             :                         "/boo",
   14742             :                         "/",
   14743             :                         "/",
   14744             :                         "/",
   14745             :                         "/",
   14746             :                         "/",
   14747             :                         "/",
   14748             :                         "/...",
   14749             :                         "/.foo",
   14750             :                         "/.foo.",
   14751             :                         "/foo.",
   14752             :                         "/foo",
   14753             :                         "/foo/baz",
   14754             :                         "/",
   14755             :                         "/",
   14756             :                         "/baz",
   14757             :                         "/a/component/path",
   14758             :                         "/a/component/path",
   14759             :                         "/a/component",
   14760             :                         "/a/path",
   14761             :                         "/a/path",
   14762             :                         NULL
   14763             :                         };
   14764           1 :         unsigned int i;
   14765             : 
   14766          28 :         for (i = 0; src[i] != NULL; i++) {
   14767          27 :                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
   14768          27 :                 if (d == NULL) {
   14769           0 :                         perror("talloc fail\n");
   14770           0 :                         return false;
   14771             :                 }
   14772          27 :                 if (strcmp(d, dst[i]) != 0) {
   14773           0 :                         d_fprintf(stderr,
   14774             :                                 "canonicalize mismatch %s -> %s != %s",
   14775             :                                 src[i], d, dst[i]);
   14776           0 :                         return false;
   14777             :                 }
   14778          27 :                 talloc_free(d);
   14779             :         }
   14780           0 :         return true;
   14781             : }
   14782             : struct session_setup_nt1_truncated_state {
   14783             :         uint16_t vwv[13];
   14784             :         uint8_t bytes[20];
   14785             : };
   14786             : 
   14787             : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
   14788             : 
   14789           2 : static struct tevent_req *smb1_session_setup_nt1_truncated_send(
   14790             :                 TALLOC_CTX *mem_ctx,
   14791             :                 struct tevent_context *ev,
   14792             :                 struct smbXcli_conn *conn)
   14793             : {
   14794           2 :         uint16_t *vwv = NULL;
   14795           2 :         uint8_t *bytes = NULL;
   14796           2 :         const char *pass = "12345678";
   14797           2 :         const char *uname = "z";
   14798           2 :         struct session_setup_nt1_truncated_state *state = NULL;
   14799           2 :         struct tevent_req *req = NULL;
   14800           2 :         struct tevent_req *subreq = NULL;
   14801             : 
   14802           2 :         req = tevent_req_create(mem_ctx,
   14803             :                                 &state,
   14804             :                                 struct session_setup_nt1_truncated_state);
   14805           2 :         if (req == NULL) {
   14806           0 :                 return NULL;
   14807             :         }
   14808           2 :         vwv = &state->vwv[0];
   14809           2 :         bytes = &state->bytes[0];
   14810             : 
   14811           2 :         SCVAL(vwv+0,  0, 0xff);
   14812           2 :         SCVAL(vwv+0,  1, 0);
   14813           2 :         SSVAL(vwv+1,  0, 0);
   14814           2 :         SSVAL(vwv+2,  0, 8192);
   14815           2 :         SSVAL(vwv+3,  0, 2);
   14816           2 :         SSVAL(vwv+4,  0, 1);
   14817           2 :         SIVAL(vwv+5,  0, 0);
   14818           2 :         SSVAL(vwv+7,  0, strlen(pass)); /* OEMPasswordLen */
   14819           2 :         SSVAL(vwv+8,  0, 0); /* UnicodePasswordLen */
   14820           2 :         SSVAL(vwv+9,  0, 0); /* reserved */
   14821           2 :         SSVAL(vwv+10, 0, 0); /* reserved */
   14822           2 :         SIVAL(vwv+11, 0, CAP_STATUS32);
   14823             : 
   14824           2 :         memcpy(bytes, pass, strlen(pass));
   14825           2 :         bytes += strlen(pass);
   14826           2 :         memcpy(bytes, uname, strlen(uname)+1);
   14827             : 
   14828           2 :         subreq = smb1cli_req_send(state, ev, conn,
   14829             :                                   SMBsesssetupX,
   14830             :                                   0, /*  additional_flags */
   14831             :                                   0, /*  clear_flags */
   14832             :                                   0, /*  additional_flags2 */
   14833             :                                   0, /*  clear_flags2 */
   14834             :                                   10000, /* timeout_msec */
   14835           2 :                                   getpid(),
   14836             :                                   NULL, /* tcon */
   14837             :                                   NULL, /* session */
   14838             :                                   13, /* wct */
   14839           2 :                                   state->vwv,
   14840           2 :                                   strlen(pass), /* Truncate length at password. */
   14841           2 :                                   state->bytes);
   14842           2 :         if (tevent_req_nomem(subreq, req)) {
   14843           0 :                 return tevent_req_post(req, ev);
   14844             :         }
   14845           2 :         tevent_req_set_callback(subreq,
   14846             :                                 smb1_session_setup_nt1_truncated_done,
   14847             :                                 req);
   14848           2 :         return req;
   14849             : }
   14850             : 
   14851           2 : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
   14852             : {
   14853           0 :         struct tevent_req *req =
   14854           2 :                 tevent_req_callback_data(subreq,
   14855             :                 struct tevent_req);
   14856           0 :         struct session_setup_nt1_truncated_state *state =
   14857           2 :                 tevent_req_data(req,
   14858             :                 struct session_setup_nt1_truncated_state);
   14859           0 :         NTSTATUS status;
   14860           2 :         struct smb1cli_req_expected_response expected[] = {
   14861             :         {
   14862             :                 .status = NT_STATUS_OK,
   14863             :                 .wct    = 3,
   14864             :         },
   14865             :         };
   14866             : 
   14867           2 :         status = smb1cli_req_recv(subreq, state,
   14868             :                                   NULL,
   14869             :                                   NULL,
   14870             :                                   NULL,
   14871             :                                   NULL,
   14872             :                                   NULL, /* pvwv_offset */
   14873             :                                   NULL,
   14874             :                                   NULL,
   14875             :                                   NULL, /* pbytes_offset */
   14876             :                                   NULL,
   14877             :                                   expected, ARRAY_SIZE(expected));
   14878           2 :         TALLOC_FREE(subreq);
   14879           2 :         if (tevent_req_nterror(req, status)) {
   14880           0 :                 return;
   14881             :         }
   14882           2 :         tevent_req_done(req);
   14883             : }
   14884             : 
   14885           2 : static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
   14886             : {
   14887           2 :         return tevent_req_simple_recv_ntstatus(req);
   14888             : }
   14889             : 
   14890           2 : static bool run_smb1_truncated_sesssetup(int dummy)
   14891             : {
   14892           0 :         struct tevent_context *ev;
   14893           0 :         struct tevent_req *req;
   14894           0 :         struct smbXcli_conn *conn;
   14895           0 :         struct sockaddr_storage ss;
   14896           0 :         NTSTATUS status;
   14897           0 :         int fd;
   14898           0 :         bool ok;
   14899             : 
   14900           2 :         printf("Starting send truncated SMB1 sesssetup.\n");
   14901             : 
   14902           2 :         ok = resolve_name(host, &ss, 0x20, true);
   14903           2 :         if (!ok) {
   14904           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14905           0 :                 return false;
   14906             :         }
   14907             : 
   14908           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14909           2 :         if (!NT_STATUS_IS_OK(status)) {
   14910           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14911             :                           nt_errstr(status));
   14912           0 :                 return false;
   14913             :         }
   14914             : 
   14915           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14916             :                                    NULL, 0, NULL);
   14917           2 :         if (conn == NULL) {
   14918           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14919           0 :                 return false;
   14920             :         }
   14921             : 
   14922           2 :         status = smbXcli_negprot(conn,
   14923             :                                  0,
   14924             :                                  PROTOCOL_NT1,
   14925             :                                  PROTOCOL_NT1,
   14926             :                                  NULL,
   14927             :                                  NULL,
   14928             :                                  NULL);
   14929           2 :         if (!NT_STATUS_IS_OK(status)) {
   14930           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   14931           0 :                 return false;
   14932             :         }
   14933             : 
   14934           2 :         ev = samba_tevent_context_init(talloc_tos());
   14935           2 :         if (ev == NULL) {
   14936           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14937           0 :                 return false;
   14938             :         }
   14939             : 
   14940           2 :         req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
   14941           2 :         if (req == NULL) {
   14942           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
   14943           0 :                 return false;
   14944             :         }
   14945             : 
   14946           2 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   14947           2 :         if (!ok) {
   14948           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   14949             :                         nt_errstr(status));
   14950           0 :                 return false;
   14951             :         }
   14952             : 
   14953           2 :         status = smb1_session_setup_nt1_truncated_recv(req);
   14954           2 :         if (!NT_STATUS_IS_OK(status)) {
   14955           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
   14956             :                           "%s, expected NT_STATUS_OK\n",
   14957             :                           nt_errstr(status));
   14958           0 :                 return false;
   14959             :         }
   14960             : 
   14961           2 :         TALLOC_FREE(conn);
   14962           2 :         return true;
   14963             : }
   14964             : 
   14965             : struct smb1_negotiate_exit_state {
   14966             :         int dummy;
   14967             : };
   14968             : 
   14969             : static void smb1_negotiate_exit_done(struct tevent_req *subreq);
   14970             : 
   14971           4 : static struct tevent_req *smb1_negotiate_exit_send(
   14972             :                 TALLOC_CTX *mem_ctx,
   14973             :                 struct tevent_context *ev,
   14974             :                 struct smbXcli_conn *conn)
   14975             : {
   14976           4 :         struct smb1_negotiate_exit_state *state = NULL;
   14977           4 :         struct tevent_req *req = NULL;
   14978           4 :         struct tevent_req *subreq = NULL;
   14979             : 
   14980           4 :         req = tevent_req_create(mem_ctx,
   14981             :                                 &state,
   14982             :                                 struct smb1_negotiate_exit_state);
   14983           4 :         if (req == NULL) {
   14984           0 :                 return NULL;
   14985             :         }
   14986           4 :         subreq = smb1cli_req_send(state, ev, conn,
   14987             :                                   SMBexit,
   14988             :                                   0, /*  additional_flags */
   14989             :                                   0, /*  clear_flags */
   14990             :                                   0, /*  additional_flags2 */
   14991             :                                   0, /*  clear_flags2 */
   14992             :                                   10000, /* timeout_msec */
   14993           4 :                                   getpid(),
   14994             :                                   NULL, /* tcon */
   14995             :                                   NULL, /* session */
   14996             :                                   0, /* wct */
   14997             :                                   NULL,
   14998             :                                   0,
   14999             :                                   NULL);
   15000           4 :         if (tevent_req_nomem(subreq, req)) {
   15001           0 :                 return tevent_req_post(req, ev);
   15002             :         }
   15003           4 :         tevent_req_set_callback(subreq,
   15004             :                                 smb1_negotiate_exit_done,
   15005             :                                 req);
   15006           4 :         return req;
   15007             : }
   15008             : 
   15009           4 : static void smb1_negotiate_exit_done(struct tevent_req *subreq)
   15010             : {
   15011           0 :         struct tevent_req *req =
   15012           4 :                 tevent_req_callback_data(subreq,
   15013             :                 struct tevent_req);
   15014           0 :         struct smb1_negotiate_exit_state *state =
   15015           4 :                 tevent_req_data(req,
   15016             :                 struct smb1_negotiate_exit_state);
   15017           0 :         NTSTATUS status;
   15018           4 :         struct smb1cli_req_expected_response expected[] = {
   15019             :         {
   15020             :                 .status = NT_STATUS_OK,
   15021             :                 .wct    = 0,
   15022             :         },
   15023             :         };
   15024             : 
   15025           4 :         status = smb1cli_req_recv(subreq, state,
   15026             :                                   NULL,
   15027             :                                   NULL,
   15028             :                                   NULL,
   15029             :                                   NULL,
   15030             :                                   NULL, /* pvwv_offset */
   15031             :                                   NULL,
   15032             :                                   NULL,
   15033             :                                   NULL, /* pbytes_offset */
   15034             :                                   NULL,
   15035             :                                   expected, ARRAY_SIZE(expected));
   15036           4 :         TALLOC_FREE(subreq);
   15037           4 :         if (tevent_req_nterror(req, status)) {
   15038           4 :                 return;
   15039             :         }
   15040           0 :         tevent_req_done(req);
   15041             : }
   15042             : 
   15043           4 : static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
   15044             : {
   15045           4 :         return tevent_req_simple_recv_ntstatus(req);
   15046             : }
   15047             : 
   15048           4 : static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
   15049             :                          struct tevent_context *ev,
   15050             :                          struct smbXcli_conn *conn)
   15051             : {
   15052           0 :         struct tevent_req *req;
   15053           0 :         bool ok;
   15054           0 :         NTSTATUS status;
   15055           4 :         NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
   15056             : 
   15057           4 :         req = smb1_negotiate_exit_send(ev, ev, conn);
   15058           4 :         if (req == NULL) {
   15059           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
   15060           0 :                 return false;
   15061             :         }
   15062             : 
   15063           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15064           4 :         if (!ok) {
   15065           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   15066             :                         nt_errstr(status));
   15067           0 :                 return false;
   15068             :         }
   15069             : 
   15070           4 :         status = smb1_negotiate_exit_recv(req);
   15071           4 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   15072           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
   15073             :                           "%s, expected ERRSRV, ERRinvnid\n",
   15074             :                           nt_errstr(status));
   15075           0 :                 return false;
   15076             :         }
   15077           4 :         return true;
   15078             : }
   15079             : 
   15080           2 : static bool run_smb1_negotiate_exit(int dummy)
   15081             : {
   15082           0 :         struct tevent_context *ev;
   15083           0 :         struct smbXcli_conn *conn;
   15084           0 :         struct sockaddr_storage ss;
   15085           0 :         NTSTATUS status;
   15086           0 :         int fd;
   15087           0 :         bool ok;
   15088             : 
   15089           2 :         printf("Starting send SMB1 negotiate+exit.\n");
   15090             : 
   15091           2 :         ok = resolve_name(host, &ss, 0x20, true);
   15092           2 :         if (!ok) {
   15093           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15094           0 :                 return false;
   15095             :         }
   15096             : 
   15097           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15098           2 :         if (!NT_STATUS_IS_OK(status)) {
   15099           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15100             :                           nt_errstr(status));
   15101           0 :                 return false;
   15102             :         }
   15103             : 
   15104           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15105             :                                    NULL, 0, NULL);
   15106           2 :         if (conn == NULL) {
   15107           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15108           0 :                 return false;
   15109             :         }
   15110             : 
   15111           2 :         status = smbXcli_negprot(conn,
   15112             :                                  0,
   15113             :                                  PROTOCOL_NT1,
   15114             :                                  PROTOCOL_NT1,
   15115             :                                  NULL,
   15116             :                                  NULL,
   15117             :                                  NULL);
   15118           2 :         if (!NT_STATUS_IS_OK(status)) {
   15119           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   15120           0 :                 return false;
   15121             :         }
   15122             : 
   15123           2 :         ev = samba_tevent_context_init(talloc_tos());
   15124           2 :         if (ev == NULL) {
   15125           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15126           0 :                 return false;
   15127             :         }
   15128             : 
   15129             :         /*
   15130             :          * Call do_smb1_exit twice to catch a server crash, the
   15131             :          * server sends the first return code then crashes.
   15132             :          */
   15133           2 :         ok = do_smb1_exit(ev, ev, conn);
   15134           2 :         if (!ok) {
   15135           0 :                 d_fprintf(stderr, "do_smb1_exit (1) failed\n");
   15136           0 :                 return false;
   15137             :         }
   15138           2 :         ok = do_smb1_exit(ev, ev, conn);
   15139           2 :         if (!ok) {
   15140           0 :                 d_fprintf(stderr, "do_smb1_exit (2) failed\n");
   15141           0 :                 return false;
   15142             :         }
   15143             : 
   15144           2 :         TALLOC_FREE(conn);
   15145           2 :         return true;
   15146             : }
   15147             : 
   15148           2 : static bool run_smb1_negotiate_tcon(int dummy)
   15149             : {
   15150           2 :         struct cli_state *cli = NULL;
   15151           2 :         uint16_t cnum = 0;
   15152           2 :         uint16_t max_xmit = 0;
   15153           0 :         NTSTATUS status;
   15154             : 
   15155           2 :         printf("Starting send SMB1 negotiate+tcon.\n");
   15156           2 :         cli = open_nbt_connection();
   15157           2 :         if (cli == NULL) {
   15158           0 :                 d_fprintf(stderr, "open_nbt_connection failed!\n");
   15159           0 :                 return false;
   15160             :         }
   15161           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   15162             : 
   15163           2 :         status = smbXcli_negprot(cli->conn,
   15164             :                                  0,
   15165             :                                  PROTOCOL_NT1,
   15166             :                                  PROTOCOL_NT1,
   15167             :                                  NULL,
   15168             :                                  NULL,
   15169             :                                  NULL);
   15170           2 :         if (!NT_STATUS_IS_OK(status)) {
   15171           0 :                 d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
   15172             :                         nt_errstr(status));
   15173           0 :                 return false;
   15174             :         }
   15175           2 :         status = cli_raw_tcon(cli,
   15176             :                               share,
   15177             :                               "",
   15178             :                               "?????",
   15179             :                               &max_xmit,
   15180             :                               &cnum);
   15181           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
   15182           0 :                 d_fprintf(stderr, "cli_raw_tcon failed - got %s "
   15183             :                         "(should get NT_STATUS_ACCESS_DENIED)!\n",
   15184             :                         nt_errstr(status));
   15185           0 :                 return false;
   15186             :         }
   15187           2 :         return true;
   15188             : }
   15189             : 
   15190           0 : static bool run_ign_bad_negprot(int dummy)
   15191             : {
   15192           0 :         struct tevent_context *ev;
   15193           0 :         struct tevent_req *req;
   15194           0 :         struct smbXcli_conn *conn;
   15195           0 :         struct sockaddr_storage ss;
   15196           0 :         NTSTATUS status;
   15197           0 :         int fd;
   15198           0 :         bool ok;
   15199             : 
   15200           0 :         printf("starting ignore bad negprot\n");
   15201             : 
   15202           0 :         ok = resolve_name(host, &ss, 0x20, true);
   15203           0 :         if (!ok) {
   15204           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15205           0 :                 return false;
   15206             :         }
   15207             : 
   15208           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15209           0 :         if (!NT_STATUS_IS_OK(status)) {
   15210           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15211             :                           nt_errstr(status));
   15212           0 :                 return false;
   15213             :         }
   15214             : 
   15215           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15216             :                                    NULL, 0, NULL);
   15217           0 :         if (conn == NULL) {
   15218           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15219           0 :                 return false;
   15220             :         }
   15221             : 
   15222           0 :         status = smbXcli_negprot(conn,
   15223             :                                  0,
   15224             :                                  PROTOCOL_CORE,
   15225             :                                  PROTOCOL_CORE,
   15226             :                                  NULL,
   15227             :                                  NULL,
   15228             :                                  NULL);
   15229           0 :         if (NT_STATUS_IS_OK(status)) {
   15230           0 :                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
   15231           0 :                 return false;
   15232             :         }
   15233             : 
   15234           0 :         ev = samba_tevent_context_init(talloc_tos());
   15235           0 :         if (ev == NULL) {
   15236           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15237           0 :                 return false;
   15238             :         }
   15239             : 
   15240           0 :         req = smb1cli_session_setup_nt1_send(
   15241           0 :                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
   15242             :                 data_blob_null, data_blob_null, 0x40,
   15243             :                 "Windows 2000 2195", "Windows 2000 5.0");
   15244           0 :         if (req == NULL) {
   15245           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
   15246           0 :                 return false;
   15247             :         }
   15248             : 
   15249           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15250           0 :         if (!ok) {
   15251           0 :                 d_fprintf(stderr, "tevent_req_poll failed\n");
   15252           0 :                 return false;
   15253             :         }
   15254             : 
   15255           0 :         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
   15256             :                                                 NULL, NULL);
   15257           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
   15258           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
   15259             :                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
   15260             :                           nt_errstr(status));
   15261           0 :                 return false;
   15262             :         }
   15263             : 
   15264           0 :         TALLOC_FREE(conn);
   15265             : 
   15266           0 :         printf("starting ignore bad negprot\n");
   15267             : 
   15268           0 :         return true;
   15269             : }
   15270             : 
   15271             : 
   15272          16 : static double create_procs(bool (*fn)(int), bool *result)
   15273             : {
   15274           0 :         int i, status;
   15275           0 :         volatile pid_t *child_status;
   15276           0 :         volatile bool *child_status_out;
   15277           0 :         int synccount;
   15278          16 :         int tries = 8;
   15279           0 :         struct timeval start;
   15280             : 
   15281          16 :         synccount = 0;
   15282             : 
   15283          16 :         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
   15284          16 :         if (!child_status) {
   15285           0 :                 printf("Failed to setup shared memory\n");
   15286           0 :                 return -1;
   15287             :         }
   15288             : 
   15289          16 :         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
   15290          16 :         if (!child_status_out) {
   15291           0 :                 printf("Failed to setup result status shared memory\n");
   15292           0 :                 return -1;
   15293             :         }
   15294             : 
   15295          32 :         for (i = 0; i < torture_nprocs; i++) {
   15296          16 :                 child_status[i] = 0;
   15297          16 :                 child_status_out[i] = True;
   15298             :         }
   15299             : 
   15300          16 :         start = timeval_current();
   15301             : 
   15302          32 :         for (i=0;i<torture_nprocs;i++) {
   15303          16 :                 procnum = i;
   15304          16 :                 if (fork() == 0) {
   15305           0 :                         pid_t mypid = getpid();
   15306           0 :                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
   15307             : 
   15308           0 :                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
   15309             : 
   15310           0 :                         while (1) {
   15311           0 :                                 if (torture_open_connection(&current_cli, i)) break;
   15312           0 :                                 if (tries-- == 0) {
   15313           0 :                                         printf("pid %d failed to start\n", (int)getpid());
   15314           0 :                                         _exit(1);
   15315             :                                 }
   15316           0 :                                 smb_msleep(10); 
   15317             :                         }
   15318             : 
   15319           0 :                         child_status[i] = getpid();
   15320             : 
   15321           0 :                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
   15322             : 
   15323           0 :                         child_status_out[i] = fn(i);
   15324           0 :                         _exit(0);
   15325             :                 }
   15326             :         }
   15327             : 
   15328           0 :         do {
   15329          73 :                 synccount = 0;
   15330         146 :                 for (i=0;i<torture_nprocs;i++) {
   15331          73 :                         if (child_status[i]) synccount++;
   15332             :                 }
   15333          73 :                 if (synccount == torture_nprocs) break;
   15334          57 :                 smb_msleep(10);
   15335          57 :         } while (timeval_elapsed(&start) < 30);
   15336             : 
   15337          16 :         if (synccount != torture_nprocs) {
   15338           0 :                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
   15339           0 :                 *result = False;
   15340           0 :                 return timeval_elapsed(&start);
   15341             :         }
   15342             : 
   15343             :         /* start the client load */
   15344          16 :         start = timeval_current();
   15345             : 
   15346          32 :         for (i=0;i<torture_nprocs;i++) {
   15347          16 :                 child_status[i] = 0;
   15348             :         }
   15349             : 
   15350          16 :         printf("%d clients started\n", torture_nprocs);
   15351             : 
   15352          32 :         for (i=0;i<torture_nprocs;i++) {
   15353          16 :                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
   15354             :         }
   15355             : 
   15356          16 :         printf("\n");
   15357             : 
   15358          32 :         for (i=0;i<torture_nprocs;i++) {
   15359          16 :                 if (!child_status_out[i]) {
   15360           2 :                         *result = False;
   15361             :                 }
   15362             :         }
   15363          16 :         return timeval_elapsed(&start);
   15364             : }
   15365             : 
   15366             : #define FLAG_MULTIPROC 1
   15367             : 
   15368             : static struct {
   15369             :         const char *name;
   15370             :         bool (*fn)(int);
   15371             :         unsigned flags;
   15372             : } torture_ops[] = {
   15373             :         {
   15374             :                 .name = "FDPASS",
   15375             :                 .fn   = run_fdpasstest,
   15376             :         },
   15377             :         {
   15378             :                 .name = "LOCK1",
   15379             :                 .fn   = run_locktest1,
   15380             :         },
   15381             :         {
   15382             :                 .name = "LOCK2",
   15383             :                 .fn   =  run_locktest2,
   15384             :         },
   15385             :         {
   15386             :                 .name = "LOCK3",
   15387             :                 .fn   =  run_locktest3,
   15388             :         },
   15389             :         {
   15390             :                 .name = "LOCK4",
   15391             :                 .fn   =  run_locktest4,
   15392             :         },
   15393             :         {
   15394             :                 .name = "LOCK5",
   15395             :                 .fn   =  run_locktest5,
   15396             :         },
   15397             :         {
   15398             :                 .name = "LOCK6",
   15399             :                 .fn   =  run_locktest6,
   15400             :         },
   15401             :         {
   15402             :                 .name = "LOCK7",
   15403             :                 .fn   =  run_locktest7,
   15404             :         },
   15405             :         {
   15406             :                 .name = "LOCK8",
   15407             :                 .fn   =  run_locktest8,
   15408             :         },
   15409             :         {
   15410             :                 .name = "LOCK9A",
   15411             :                 .fn   =  run_locktest9a,
   15412             :         },
   15413             :         {
   15414             :                 .name = "LOCK9B",
   15415             :                 .fn   =  run_locktest9b,
   15416             :         },
   15417             :         {
   15418             :                 .name = "LOCK10",
   15419             :                 .fn   =  run_locktest10,
   15420             :         },
   15421             :         {
   15422             :                 .name = "LOCK11",
   15423             :                 .fn   =  run_locktest11,
   15424             :         },
   15425             :         {
   15426             :                 .name = "LOCK12",
   15427             :                 .fn   =  run_locktest12,
   15428             :         },
   15429             :         {
   15430             :                 .name = "LOCK13",
   15431             :                 .fn   =  run_locktest13,
   15432             :         },
   15433             :         {
   15434             :                 .name = "UNLINK",
   15435             :                 .fn   = run_unlinktest,
   15436             :         },
   15437             :         {
   15438             :                 .name = "BROWSE",
   15439             :                 .fn   = run_browsetest,
   15440             :         },
   15441             :         {
   15442             :                 .name = "ATTR",
   15443             :                 .fn   =   run_attrtest,
   15444             :         },
   15445             :         {
   15446             :                 .name = "TRANS2",
   15447             :                 .fn   = run_trans2test,
   15448             :         },
   15449             :         {
   15450             :                 .name  = "MAXFID",
   15451             :                 .fn    = run_maxfidtest,
   15452             :                 .flags = FLAG_MULTIPROC,
   15453             :         },
   15454             :         {
   15455             :                 .name  = "TORTURE",
   15456             :                 .fn    = run_torture,
   15457             :                 .flags = FLAG_MULTIPROC,
   15458             :         },
   15459             :         {
   15460             :                 .name  = "RANDOMIPC",
   15461             :                 .fn    = run_randomipc,
   15462             :         },
   15463             :         {
   15464             :                 .name  = "NEGNOWAIT",
   15465             :                 .fn    = run_negprot_nowait,
   15466             :         },
   15467             :         {
   15468             :                 .name  = "NBENCH",
   15469             :                 .fn    =  run_nbench,
   15470             :         },
   15471             :         {
   15472             :                 .name  = "NBENCH2",
   15473             :                 .fn    = run_nbench2,
   15474             :         },
   15475             :         {
   15476             :                 .name  = "OPLOCK1",
   15477             :                 .fn    =  run_oplock1,
   15478             :         },
   15479             :         {
   15480             :                 .name  = "OPLOCK2",
   15481             :                 .fn    =  run_oplock2,
   15482             :         },
   15483             :         {
   15484             :                 .name  = "OPLOCK4",
   15485             :                 .fn    =  run_oplock4,
   15486             :         },
   15487             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
   15488             :         {
   15489             :                 .name  = "OPLOCK5",
   15490             :                 .fn    =  run_oplock5,
   15491             :         },
   15492             : #endif
   15493             :         {
   15494             :                 .name  = "DIR",
   15495             :                 .fn    =  run_dirtest,
   15496             :         },
   15497             :         {
   15498             :                 .name  = "DIR1",
   15499             :                 .fn    =  run_dirtest1,
   15500             :         },
   15501             :         {
   15502             :                 .name  = "DIR-CREATETIME",
   15503             :                 .fn    =  run_dir_createtime,
   15504             :         },
   15505             :         {
   15506             :                 .name  = "DENY1",
   15507             :                 .fn    =  torture_denytest1,
   15508             :         },
   15509             :         {
   15510             :                 .name  = "DENY2",
   15511             :                 .fn    =  torture_denytest2,
   15512             :         },
   15513             :         {
   15514             :                 .name  = "TCON",
   15515             :                 .fn    =  run_tcon_test,
   15516             :         },
   15517             :         {
   15518             :                 .name  = "TCONDEV",
   15519             :                 .fn    =  run_tcon_devtype_test,
   15520             :         },
   15521             :         {
   15522             :                 .name  = "RW1",
   15523             :                 .fn    =  run_readwritetest,
   15524             :         },
   15525             :         {
   15526             :                 .name  = "RW2",
   15527             :                 .fn    =  run_readwritemulti,
   15528             :                 .flags = FLAG_MULTIPROC
   15529             :         },
   15530             :         {
   15531             :                 .name  = "RW3",
   15532             :                 .fn    =  run_readwritelarge,
   15533             :         },
   15534             :         {
   15535             :                 .name  = "RW-SIGNING",
   15536             :                 .fn    =  run_readwritelarge_signtest,
   15537             :         },
   15538             :         {
   15539             :                 .name  = "OPEN",
   15540             :                 .fn    = run_opentest,
   15541             :         },
   15542             :         {
   15543             :                 .name  = "POSIX",
   15544             :                 .fn    = run_simple_posix_open_test,
   15545             :         },
   15546             :         {
   15547             :                 .name  = "POSIX-APPEND",
   15548             :                 .fn    = run_posix_append,
   15549             :         },
   15550             :         {
   15551             :                 .name  = "POSIX-SYMLINK-ACL",
   15552             :                 .fn    = run_acl_symlink_test,
   15553             :         },
   15554             :         {
   15555             :                 .name  = "POSIX-SYMLINK-EA",
   15556             :                 .fn    = run_ea_symlink_test,
   15557             :         },
   15558             :         {
   15559             :                 .name  = "POSIX-STREAM-DELETE",
   15560             :                 .fn    = run_posix_stream_delete,
   15561             :         },
   15562             :         {
   15563             :                 .name  = "POSIX-OFD-LOCK",
   15564             :                 .fn    = run_posix_ofd_lock_test,
   15565             :         },
   15566             :         {
   15567             :                 .name  = "POSIX-BLOCKING-LOCK",
   15568             :                 .fn    = run_posix_blocking_lock,
   15569             :         },
   15570             :         {
   15571             :                 .name  = "POSIX-MKDIR",
   15572             :                 .fn    = run_posix_mkdir_test,
   15573             :         },
   15574             :         {
   15575             :                 .name  = "POSIX-ACL-OPLOCK",
   15576             :                 .fn    = run_posix_acl_oplock_test,
   15577             :         },
   15578             :         {
   15579             :                 .name  = "POSIX-ACL-SHAREROOT",
   15580             :                 .fn    = run_posix_acl_shareroot_test,
   15581             :         },
   15582             :         {
   15583             :                 .name  = "POSIX-LS-WILDCARD",
   15584             :                 .fn    = run_posix_ls_wildcard_test,
   15585             :         },
   15586             :         {
   15587             :                 .name  = "POSIX-LS-SINGLE",
   15588             :                 .fn    = run_posix_ls_single_test,
   15589             :         },
   15590             :         {
   15591             :                 .name  = "POSIX-READLINK",
   15592             :                 .fn    = run_posix_readlink_test,
   15593             :         },
   15594             :         {
   15595             :                 .name  = "POSIX-STAT",
   15596             :                 .fn    = run_posix_stat_test,
   15597             :         },
   15598             :         {
   15599             :                 .name  = "POSIX-SYMLINK-PARENT",
   15600             :                 .fn    = run_posix_symlink_parent_test,
   15601             :         },
   15602             :         {
   15603             :                 .name  = "POSIX-SYMLINK-CHMOD",
   15604             :                 .fn    = run_posix_symlink_chmod_test,
   15605             :         },
   15606             :         {
   15607             :                 .name  = "POSIX-SYMLINK-RENAME",
   15608             :                 .fn    = run_posix_symlink_rename_test,
   15609             :         },
   15610             :         {
   15611             :                 .name  = "POSIX-DIR-DEFAULT-ACL",
   15612             :                 .fn    = run_posix_dir_default_acl_test,
   15613             :         },
   15614             :         {
   15615             :                 .name  = "POSIX-SYMLINK-GETPATHINFO",
   15616             :                 .fn    = run_posix_symlink_getpathinfo_test,
   15617             :         },
   15618             :         {
   15619             :                 .name  = "POSIX-SYMLINK-SETPATHINFO",
   15620             :                 .fn    = run_posix_symlink_setpathinfo_test,
   15621             :         },
   15622             :         {
   15623             :                 .name  = "WINDOWS-BAD-SYMLINK",
   15624             :                 .fn    = run_symlink_open_test,
   15625             :         },
   15626             :         {
   15627             :                 .name  = "SMB1-WILD-MANGLE-UNLINK",
   15628             :                 .fn    = run_smb1_wild_mangle_unlink_test,
   15629             :         },
   15630             :         {
   15631             :                 .name  = "SMB1-WILD-MANGLE-RENAME",
   15632             :                 .fn    = run_smb1_wild_mangle_rename_test,
   15633             :         },
   15634             :         {
   15635             :                 .name  = "CASE-INSENSITIVE-CREATE",
   15636             :                 .fn    = run_case_insensitive_create,
   15637             :         },
   15638             :         {
   15639             :                 .name  = "ASYNC-ECHO",
   15640             :                 .fn    = run_async_echo,
   15641             :         },
   15642             :         {
   15643             :                 .name  = "UID-REGRESSION-TEST",
   15644             :                 .fn    = run_uid_regression_test,
   15645             :         },
   15646             :         {
   15647             :                 .name  = "SHORTNAME-TEST",
   15648             :                 .fn    = run_shortname_test,
   15649             :         },
   15650             :         {
   15651             :                 .name  = "ADDRCHANGE",
   15652             :                 .fn    = run_addrchange,
   15653             :         },
   15654             : #if 1
   15655             :         {
   15656             :                 .name  = "OPENATTR",
   15657             :                 .fn    = run_openattrtest,
   15658             :         },
   15659             : #endif
   15660             :         {
   15661             :                 .name  = "XCOPY",
   15662             :                 .fn    = run_xcopy,
   15663             :         },
   15664             :         {
   15665             :                 .name  = "RENAME",
   15666             :                 .fn    = run_rename,
   15667             :         },
   15668             :         {
   15669             :                 .name  = "RENAME-ACCESS",
   15670             :                 .fn    = run_rename_access,
   15671             :         },
   15672             :         {
   15673             :                 .name  = "OWNER-RIGHTS",
   15674             :                 .fn    = run_owner_rights,
   15675             :         },
   15676             :         {
   15677             :                 .name  = "DELETE",
   15678             :                 .fn    = run_deletetest,
   15679             :         },
   15680             :         {
   15681             :                 .name  = "DELETE-STREAM",
   15682             :                 .fn    = run_delete_stream,
   15683             :         },
   15684             :         {
   15685             :                 .name  = "DELETE-PRINT",
   15686             :                 .fn    = run_delete_print_test,
   15687             :         },
   15688             :         {
   15689             :                 .name  = "DELETE-LN",
   15690             :                 .fn    = run_deletetest_ln,
   15691             :         },
   15692             :         {
   15693             :                 .name  = "PROPERTIES",
   15694             :                 .fn    = run_properties,
   15695             :         },
   15696             :         {
   15697             :                 .name  = "MANGLE",
   15698             :                 .fn    = torture_mangle,
   15699             :         },
   15700             :         {
   15701             :                 .name  = "MANGLE1",
   15702             :                 .fn    = run_mangle1,
   15703             :         },
   15704             :         {
   15705             :                 .name  = "MANGLE-ILLEGAL",
   15706             :                 .fn    = run_mangle_illegal,
   15707             :         },
   15708             :         {
   15709             :                 .name  = "W2K",
   15710             :                 .fn    = run_w2ktest,
   15711             :         },
   15712             :         {
   15713             :                 .name  = "TRANS2SCAN",
   15714             :                 .fn    = torture_trans2_scan,
   15715             :         },
   15716             :         {
   15717             :                 .name  = "NTTRANSSCAN",
   15718             :                 .fn    = torture_nttrans_scan,
   15719             :         },
   15720             :         {
   15721             :                 .name  = "UTABLE",
   15722             :                 .fn    = torture_utable,
   15723             :         },
   15724             :         {
   15725             :                 .name  = "CASETABLE",
   15726             :                 .fn    = torture_casetable,
   15727             :         },
   15728             :         {
   15729             :                 .name  = "ERRMAPEXTRACT",
   15730             :                 .fn    = run_error_map_extract,
   15731             :         },
   15732             :         {
   15733             :                 .name  = "PIPE_NUMBER",
   15734             :                 .fn    = run_pipe_number,
   15735             :         },
   15736             :         {
   15737             :                 .name  = "TCON2",
   15738             :                 .fn    =  run_tcon2_test,
   15739             :         },
   15740             :         {
   15741             :                 .name  = "IOCTL",
   15742             :                 .fn    =  torture_ioctl_test,
   15743             :         },
   15744             :         {
   15745             :                 .name  = "CHKPATH",
   15746             :                 .fn    =  torture_chkpath_test,
   15747             :         },
   15748             :         {
   15749             :                 .name  = "FDSESS",
   15750             :                 .fn    = run_fdsesstest,
   15751             :         },
   15752             :         {
   15753             :                 .name  = "EATEST",
   15754             :                 .fn    = run_eatest,
   15755             :         },
   15756             :         {
   15757             :                 .name  = "SESSSETUP_BENCH",
   15758             :                 .fn    = run_sesssetup_bench,
   15759             :         },
   15760             :         {
   15761             :                 .name  = "CHAIN1",
   15762             :                 .fn    = run_chain1,
   15763             :         },
   15764             :         {
   15765             :                 .name  = "CHAIN2",
   15766             :                 .fn    = run_chain2,
   15767             :         },
   15768             :         {
   15769             :                 .name  = "CHAIN3",
   15770             :                 .fn    = run_chain3,
   15771             :         },
   15772             :         {
   15773             :                 .name  = "WINDOWS-WRITE",
   15774             :                 .fn    = run_windows_write,
   15775             :         },
   15776             :         {
   15777             :                 .name  = "LARGE_READX",
   15778             :                 .fn    = run_large_readx,
   15779             :         },
   15780             :         {
   15781             :                 .name  = "MSDFS-ATTRIBUTE",
   15782             :                 .fn    = run_msdfs_attribute,
   15783             :         },
   15784             :         {
   15785             :                 .name  = "NTTRANS-CREATE",
   15786             :                 .fn    = run_nttrans_create,
   15787             :         },
   15788             :         {
   15789             :                 .name  = "NTTRANS-FSCTL",
   15790             :                 .fn    = run_nttrans_fsctl,
   15791             :         },
   15792             :         {
   15793             :                 .name  = "CLI_ECHO",
   15794             :                 .fn    = run_cli_echo,
   15795             :         },
   15796             :         {
   15797             :                 .name  = "CLI_SPLICE",
   15798             :                 .fn    = run_cli_splice,
   15799             :         },
   15800             :         {
   15801             :                 .name  = "TLDAP",
   15802             :                 .fn    = run_tldap,
   15803             :         },
   15804             :         {
   15805             :                 .name  = "STREAMERROR",
   15806             :                 .fn    = run_streamerror,
   15807             :         },
   15808             :         {
   15809             :                 .name  = "NOTIFY-BENCH",
   15810             :                 .fn    = run_notify_bench,
   15811             :         },
   15812             :         {
   15813             :                 .name  = "NOTIFY-BENCH2",
   15814             :                 .fn    = run_notify_bench2,
   15815             :         },
   15816             :         {
   15817             :                 .name  = "NOTIFY-BENCH3",
   15818             :                 .fn    = run_notify_bench3,
   15819             :         },
   15820             :         {
   15821             :                 .name  = "BAD-NBT-SESSION",
   15822             :                 .fn    = run_bad_nbt_session,
   15823             :         },
   15824             :         {
   15825             :                 .name  = "IGN-BAD-NEGPROT",
   15826             :                 .fn    = run_ign_bad_negprot,
   15827             :         },
   15828             :         {
   15829             :                 .name  = "SMB-ANY-CONNECT",
   15830             :                 .fn    = run_smb_any_connect,
   15831             :         },
   15832             :         {
   15833             :                 .name  = "NOTIFY-ONLINE",
   15834             :                 .fn    = run_notify_online,
   15835             :         },
   15836             :         {
   15837             :                 .name  = "SMB2-BASIC",
   15838             :                 .fn    = run_smb2_basic,
   15839             :         },
   15840             :         {
   15841             :                 .name  = "SMB2-NEGPROT",
   15842             :                 .fn    = run_smb2_negprot,
   15843             :         },
   15844             :         {
   15845             :                 .name  = "SMB2-ANONYMOUS",
   15846             :                 .fn    = run_smb2_anonymous,
   15847             :         },
   15848             :         {
   15849             :                 .name  = "SMB2-SESSION-RECONNECT",
   15850             :                 .fn    = run_smb2_session_reconnect,
   15851             :         },
   15852             :         {
   15853             :                 .name  = "SMB2-TCON-DEPENDENCE",
   15854             :                 .fn    = run_smb2_tcon_dependence,
   15855             :         },
   15856             :         {
   15857             :                 .name  = "SMB2-MULTI-CHANNEL",
   15858             :                 .fn    = run_smb2_multi_channel,
   15859             :         },
   15860             :         {
   15861             :                 .name  = "SMB2-SESSION-REAUTH",
   15862             :                 .fn    = run_smb2_session_reauth,
   15863             :         },
   15864             :         {
   15865             :                 .name  = "SMB2-FTRUNCATE",
   15866             :                 .fn    = run_smb2_ftruncate,
   15867             :         },
   15868             :         {
   15869             :                 .name  = "SMB2-DIR-FSYNC",
   15870             :                 .fn    = run_smb2_dir_fsync,
   15871             :         },
   15872             :         {
   15873             :                 .name  = "SMB2-PATH-SLASH",
   15874             :                 .fn    = run_smb2_path_slash,
   15875             :         },
   15876             :         {
   15877             :                 .name  = "SMB1-SYSTEM-SECURITY",
   15878             :                 .fn    = run_smb1_system_security,
   15879             :         },
   15880             :         {
   15881             :                 .name  = "SMB2-SACL",
   15882             :                 .fn    = run_smb2_sacl,
   15883             :         },
   15884             :         {
   15885             :                 .name  = "SMB2-QUOTA1",
   15886             :                 .fn    = run_smb2_quota1,
   15887             :         },
   15888             :         {
   15889             :                 .name  = "SMB2-INVALID-PIPENAME",
   15890             :                 .fn    = run_smb2_invalid_pipename,
   15891             :         },
   15892             :         {
   15893             :                 .name  = "SMB2-STREAM-ACL",
   15894             :                 .fn    = run_smb2_stream_acl,
   15895             :         },
   15896             :         {
   15897             :                 .name  = "SMB2-LIST-DIR-ASYNC",
   15898             :                 .fn    = run_list_dir_async_test,
   15899             :         },
   15900             :         {
   15901             :                 .name  = "SMB2-DEL-ON-CLOSE-NONEMPTY",
   15902             :                 .fn    = run_delete_on_close_non_empty,
   15903             :         },
   15904             :         {
   15905             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
   15906             :                 .fn    = run_delete_on_close_nonwrite_delete_yes_test,
   15907             :         },
   15908             :         {
   15909             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
   15910             :                 .fn    = run_delete_on_close_nonwrite_delete_no_test,
   15911             :         },
   15912             :         {
   15913             :                 .name  = "SMB2-DFS-PATHS",
   15914             :                 .fn    = run_smb2_dfs_paths,
   15915             :         },
   15916             :         {
   15917             :                 .name  = "SMB2-NON-DFS-SHARE",
   15918             :                 .fn    = run_smb2_non_dfs_share,
   15919             :         },
   15920             :         {
   15921             :                 .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
   15922             :                 .fn    = run_smb2_dfs_share_non_dfs_path,
   15923             :         },
   15924             :         {
   15925             :                 .name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
   15926             :                 .fn    = run_smb2_dfs_filename_leading_backslash,
   15927             :         },
   15928             :         {
   15929             :                 .name  = "SMB2-PIPE-READ-ASYNC-DISCONNECT",
   15930             :                 .fn    = run_smb2_pipe_read_async_disconnect,
   15931             :         },
   15932             :         {
   15933             :                 .name  = "SMB1-TRUNCATED-SESSSETUP",
   15934             :                 .fn    = run_smb1_truncated_sesssetup,
   15935             :         },
   15936             :         {
   15937             :                 .name  = "SMB1-NEGOTIATE-EXIT",
   15938             :                 .fn    = run_smb1_negotiate_exit,
   15939             :         },
   15940             :         {
   15941             :                 .name  = "SMB1-NEGOTIATE-TCON",
   15942             :                 .fn    = run_smb1_negotiate_tcon,
   15943             :         },
   15944             :         {
   15945             :                 .name  = "SMB1-DFS-PATHS",
   15946             :                 .fn    = run_smb1_dfs_paths,
   15947             :         },
   15948             :         {
   15949             :                 .name  = "SMB1-DFS-SEARCH-PATHS",
   15950             :                 .fn    = run_smb1_dfs_search_paths,
   15951             :         },
   15952             :         {
   15953             :                 .name  = "SMB1-DFS-OPERATIONS",
   15954             :                 .fn    = run_smb1_dfs_operations,
   15955             :         },
   15956             :         {
   15957             :                 .name  = "SMB1-DFS-BADPATH",
   15958             :                 .fn    = run_smb1_dfs_check_badpath,
   15959             :         },
   15960             :         {
   15961             :                 .name  = "CLEANUP1",
   15962             :                 .fn    = run_cleanup1,
   15963             :         },
   15964             :         {
   15965             :                 .name  = "CLEANUP2",
   15966             :                 .fn    = run_cleanup2,
   15967             :         },
   15968             :         {
   15969             :                 .name  = "CLEANUP4",
   15970             :                 .fn    = run_cleanup4,
   15971             :         },
   15972             :         {
   15973             :                 .name  = "OPLOCK-CANCEL",
   15974             :                 .fn    = run_oplock_cancel,
   15975             :         },
   15976             :         {
   15977             :                 .name  = "PIDHIGH",
   15978             :                 .fn    = run_pidhigh,
   15979             :         },
   15980             :         {
   15981             :                 .name  = "LOCAL-SUBSTITUTE",
   15982             :                 .fn    = run_local_substitute,
   15983             :         },
   15984             :         {
   15985             :                 .name  = "LOCAL-GENCACHE",
   15986             :                 .fn    = run_local_gencache,
   15987             :         },
   15988             :         {
   15989             :                 .name  = "LOCAL-DBWRAP-WATCH1",
   15990             :                 .fn    = run_dbwrap_watch1,
   15991             :         },
   15992             :         {
   15993             :                 .name  = "LOCAL-DBWRAP-WATCH2",
   15994             :                 .fn    = run_dbwrap_watch2,
   15995             :         },
   15996             :         {
   15997             :                 .name  = "LOCAL-DBWRAP-WATCH3",
   15998             :                 .fn    = run_dbwrap_watch3,
   15999             :         },
   16000             :         {
   16001             :                 .name  = "LOCAL-DBWRAP-WATCH4",
   16002             :                 .fn    = run_dbwrap_watch4,
   16003             :         },
   16004             :         {
   16005             :                 .name  = "LOCAL-DBWRAP-DO-LOCKED1",
   16006             :                 .fn    = run_dbwrap_do_locked1,
   16007             :         },
   16008             :         {
   16009             :                 .name  = "LOCAL-MESSAGING-READ1",
   16010             :                 .fn    = run_messaging_read1,
   16011             :         },
   16012             :         {
   16013             :                 .name  = "LOCAL-MESSAGING-READ2",
   16014             :                 .fn    = run_messaging_read2,
   16015             :         },
   16016             :         {
   16017             :                 .name  = "LOCAL-MESSAGING-READ3",
   16018             :                 .fn    = run_messaging_read3,
   16019             :         },
   16020             :         {
   16021             :                 .name  = "LOCAL-MESSAGING-READ4",
   16022             :                 .fn    = run_messaging_read4,
   16023             :         },
   16024             :         {
   16025             :                 .name  = "LOCAL-MESSAGING-FDPASS1",
   16026             :                 .fn    = run_messaging_fdpass1,
   16027             :         },
   16028             :         {
   16029             :                 .name  = "LOCAL-MESSAGING-FDPASS2",
   16030             :                 .fn    = run_messaging_fdpass2,
   16031             :         },
   16032             :         {
   16033             :                 .name  = "LOCAL-MESSAGING-FDPASS2a",
   16034             :                 .fn    = run_messaging_fdpass2a,
   16035             :         },
   16036             :         {
   16037             :                 .name  = "LOCAL-MESSAGING-FDPASS2b",
   16038             :                 .fn    = run_messaging_fdpass2b,
   16039             :         },
   16040             :         {
   16041             :                 .name  = "LOCAL-MESSAGING-SEND-ALL",
   16042             :                 .fn    = run_messaging_send_all,
   16043             :         },
   16044             :         {
   16045             :                 .name  = "LOCAL-BASE64",
   16046             :                 .fn    = run_local_base64,
   16047             :         },
   16048             :         {
   16049             :                 .name  = "LOCAL-RBTREE",
   16050             :                 .fn    = run_local_rbtree,
   16051             :         },
   16052             :         {
   16053             :                 .name  = "LOCAL-MEMCACHE",
   16054             :                 .fn    = run_local_memcache,
   16055             :         },
   16056             :         {
   16057             :                 .name  = "LOCAL-STREAM-NAME",
   16058             :                 .fn    = run_local_stream_name,
   16059             :         },
   16060             :         {
   16061             :                 .name  = "LOCAL-STR-MATCH-MSWILD",
   16062             :                 .fn    = run_str_match_mswild,
   16063             :         },
   16064             :         {
   16065             :                 .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
   16066             :                 .fn    = run_str_match_regex_sub1,
   16067             :         },
   16068             :         {
   16069             :                 .name  = "WBCLIENT-MULTI-PING",
   16070             :                 .fn    = run_wbclient_multi_ping,
   16071             :         },
   16072             :         {
   16073             :                 .name  = "LOCAL-string_to_sid",
   16074             :                 .fn    = run_local_string_to_sid,
   16075             :         },
   16076             :         {
   16077             :                 .name  = "LOCAL-sid_to_string",
   16078             :                 .fn    = run_local_sid_to_string,
   16079             :         },
   16080             :         {
   16081             :                 .name  = "LOCAL-binary_to_sid",
   16082             :                 .fn    = run_local_binary_to_sid,
   16083             :         },
   16084             :         {
   16085             :                 .name  = "LOCAL-DBTRANS",
   16086             :                 .fn    = run_local_dbtrans,
   16087             :         },
   16088             :         {
   16089             :                 .name  = "LOCAL-TEVENT-POLL",
   16090             :                 .fn    = run_local_tevent_poll,
   16091             :         },
   16092             :         {
   16093             :                 .name  = "LOCAL-CONVERT-STRING",
   16094             :                 .fn    = run_local_convert_string,
   16095             :         },
   16096             :         {
   16097             :                 .name  = "LOCAL-CONV-AUTH-INFO",
   16098             :                 .fn    = run_local_conv_auth_info,
   16099             :         },
   16100             :         {
   16101             :                 .name  = "LOCAL-hex_encode_buf",
   16102             :                 .fn    = run_local_hex_encode_buf,
   16103             :         },
   16104             :         {
   16105             :                 .name  = "LOCAL-IDMAP-TDB-COMMON",
   16106             :                 .fn    = run_idmap_tdb_common_test,
   16107             :         },
   16108             :         {
   16109             :                 .name  = "LOCAL-remove_duplicate_addrs2",
   16110             :                 .fn    = run_local_remove_duplicate_addrs2,
   16111             :         },
   16112             :         {
   16113             :                 .name  = "local-tdb-opener",
   16114             :                 .fn    = run_local_tdb_opener,
   16115             :         },
   16116             :         {
   16117             :                 .name  = "local-tdb-writer",
   16118             :                 .fn    = run_local_tdb_writer,
   16119             :         },
   16120             :         {
   16121             :                 .name  = "LOCAL-DBWRAP-CTDB1",
   16122             :                 .fn    = run_local_dbwrap_ctdb1,
   16123             :         },
   16124             :         {
   16125             :                 .name  = "LOCAL-BENCH-PTHREADPOOL",
   16126             :                 .fn    = run_bench_pthreadpool,
   16127             :         },
   16128             :         {
   16129             :                 .name  = "LOCAL-PTHREADPOOL-TEVENT",
   16130             :                 .fn    = run_pthreadpool_tevent,
   16131             :         },
   16132             :         {
   16133             :                 .name  = "LOCAL-G-LOCK1",
   16134             :                 .fn    = run_g_lock1,
   16135             :         },
   16136             :         {
   16137             :                 .name  = "LOCAL-G-LOCK2",
   16138             :                 .fn    = run_g_lock2,
   16139             :         },
   16140             :         {
   16141             :                 .name  = "LOCAL-G-LOCK3",
   16142             :                 .fn    = run_g_lock3,
   16143             :         },
   16144             :         {
   16145             :                 .name  = "LOCAL-G-LOCK4",
   16146             :                 .fn    = run_g_lock4,
   16147             :         },
   16148             :         {
   16149             :                 .name  = "LOCAL-G-LOCK4A",
   16150             :                 .fn    = run_g_lock4a,
   16151             :         },
   16152             :         {
   16153             :                 .name  = "LOCAL-G-LOCK5",
   16154             :                 .fn    = run_g_lock5,
   16155             :         },
   16156             :         {
   16157             :                 .name  = "LOCAL-G-LOCK6",
   16158             :                 .fn    = run_g_lock6,
   16159             :         },
   16160             :         {
   16161             :                 .name  = "LOCAL-G-LOCK7",
   16162             :                 .fn    = run_g_lock7,
   16163             :         },
   16164             :         {
   16165             :                 .name  = "LOCAL-G-LOCK8",
   16166             :                 .fn    = run_g_lock8,
   16167             :         },
   16168             :         {
   16169             :                 .name  = "LOCAL-G-LOCK-PING-PONG",
   16170             :                 .fn    = run_g_lock_ping_pong,
   16171             :         },
   16172             :         {
   16173             :                 .name  = "LOCAL-CANONICALIZE-PATH",
   16174             :                 .fn    = run_local_canonicalize_path,
   16175             :         },
   16176             :         {
   16177             :                 .name  = "LOCAL-NAMEMAP-CACHE1",
   16178             :                 .fn    = run_local_namemap_cache1,
   16179             :         },
   16180             :         {
   16181             :                 .name  = "LOCAL-IDMAP-CACHE1",
   16182             :                 .fn    = run_local_idmap_cache1,
   16183             :         },
   16184             :         {
   16185             :                 .name  = "qpathinfo-bufsize",
   16186             :                 .fn    = run_qpathinfo_bufsize,
   16187             :         },
   16188             :         {
   16189             :                 .name  = "hide-new-files-timeout",
   16190             :                 .fn    = run_hidenewfiles,
   16191             :         },
   16192             :         {
   16193             :                 .name  = "hide-new-files-timeout-showdirs",
   16194             :                 .fn    = run_hidenewfiles_showdirs,
   16195             :         },
   16196             : #ifdef CLUSTER_SUPPORT
   16197             :         {
   16198             :                 .name  = "ctdbd-conn1",
   16199             :                 .fn    = run_ctdbd_conn1,
   16200             :         },
   16201             : #endif
   16202             :         {
   16203             :                 .name  = "readdir-timestamp",
   16204             :                 .fn    = run_readdir_timestamp,
   16205             :         },
   16206             :         {
   16207             :                 .name  = "rpc-scale",
   16208             :                 .fn    = run_rpc_scale,
   16209             :         },
   16210             :         {
   16211             :                 .name  = "LOCAL-TDB-VALIDATE",
   16212             :                 .fn    = run_tdb_validate,
   16213             :         },
   16214             :         {
   16215             :                 .name = NULL,
   16216             :         },
   16217             : };
   16218             : 
   16219             : /****************************************************************************
   16220             : run a specified test or "ALL"
   16221             : ****************************************************************************/
   16222         546 : static bool run_test(const char *name)
   16223             : {
   16224         546 :         bool ret = True;
   16225         546 :         bool result = True;
   16226         546 :         bool found = False;
   16227          45 :         int i;
   16228          45 :         double t;
   16229         546 :         if (strequal(name,"ALL")) {
   16230           0 :                 for (i=0;torture_ops[i].name;i++) {
   16231           0 :                         run_test(torture_ops[i].name);
   16232             :                 }
   16233           0 :                 found = True;
   16234             :         }
   16235             : 
   16236      113747 :         for (i=0;torture_ops[i].name;i++) {
   16237      113197 :                 fstr_sprintf(randomfname, "\\XX%x", 
   16238      113197 :                          (unsigned)random());
   16239             : 
   16240      113197 :                 if (strequal(name, torture_ops[i].name)) {
   16241         546 :                         found = True;
   16242         546 :                         printf("Running %s\n", name);
   16243         546 :                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
   16244          16 :                                 t = create_procs(torture_ops[i].fn, &result);
   16245          16 :                                 if (!result) { 
   16246           2 :                                         ret = False;
   16247           2 :                                         printf("TEST %s FAILED!\n", name);
   16248             :                                 }
   16249             :                         } else {
   16250          45 :                                 struct timeval start;
   16251         530 :                                 start = timeval_current();
   16252         530 :                                 if (!torture_ops[i].fn(0)) {
   16253          14 :                                         ret = False;
   16254          14 :                                         printf("TEST %s FAILED!\n", name);
   16255             :                                 }
   16256         534 :                                 t = timeval_elapsed(&start);
   16257             :                         }
   16258        9995 :                         printf("%s took %g secs\n\n", name, t);
   16259             :                 }
   16260             :         }
   16261             : 
   16262         550 :         if (!found) {
   16263           0 :                 printf("Did not find a test named %s\n", name);
   16264           0 :                 ret = False;
   16265             :         }
   16266             : 
   16267         550 :         return ret;
   16268             : }
   16269             : 
   16270             : 
   16271           0 : static void usage(void)
   16272             : {
   16273           0 :         int i;
   16274             : 
   16275           0 :         printf("WARNING samba4 test suite is much more complete nowadays.\n");
   16276           0 :         printf("Please use samba4 torture.\n\n");
   16277             : 
   16278           0 :         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
   16279             : 
   16280           0 :         printf("\t-d debuglevel\n");
   16281           0 :         printf("\t-U user%%pass\n");
   16282           0 :         printf("\t-k                    use kerberos\n");
   16283           0 :         printf("\t-N numprocs\n");
   16284           0 :         printf("\t-n my_netbios_name\n");
   16285           0 :         printf("\t-W workgroup\n");
   16286           0 :         printf("\t-o num_operations\n");
   16287           0 :         printf("\t-O socket_options\n");
   16288           0 :         printf("\t-m maximum protocol\n");
   16289           0 :         printf("\t-L use oplocks\n");
   16290           0 :         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
   16291           0 :         printf("\t-A showall\n");
   16292           0 :         printf("\t-p port\n");
   16293           0 :         printf("\t-s seed\n");
   16294           0 :         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
   16295           0 :         printf("\t-f filename           filename to test\n");
   16296           0 :         printf("\t-e                    encrypt\n");
   16297           0 :         printf("\n\n");
   16298             : 
   16299           0 :         printf("tests are:");
   16300           0 :         for (i=0;torture_ops[i].name;i++) {
   16301           0 :                 printf(" %s", torture_ops[i].name);
   16302             :         }
   16303           0 :         printf("\n");
   16304             : 
   16305           0 :         printf("default test is ALL\n");
   16306             : 
   16307           0 :         exit(1);
   16308             : }
   16309             : 
   16310             : /****************************************************************************
   16311             :   main program
   16312             : ****************************************************************************/
   16313         546 :  int main(int argc,char *argv[])
   16314             : {
   16315          45 :         int opt, i;
   16316          45 :         char *p;
   16317         546 :         int gotuser = 0;
   16318         546 :         int gotpass = 0;
   16319         546 :         bool correct = True;
   16320         546 :         TALLOC_CTX *frame = talloc_stackframe();
   16321         546 :         int seed = time(NULL);
   16322         546 :         struct loadparm_context *lp_ctx = NULL;
   16323             : 
   16324             : #ifdef HAVE_SETBUFFER
   16325         546 :         setbuffer(stdout, NULL, 0);
   16326             : #endif
   16327             : 
   16328         546 :         setup_logging("smbtorture", DEBUG_STDOUT);
   16329             : 
   16330         546 :         smb_init_locale();
   16331         546 :         fault_setup();
   16332             : 
   16333         546 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
   16334         546 :         if (lp_ctx == NULL) {
   16335           0 :                 fprintf(stderr,
   16336             :                         "Failed to initialise the global parameter structure.\n");
   16337           0 :                 return 1;
   16338             :         }
   16339             : 
   16340         546 :         if (is_default_dyn_CONFIGFILE()) {
   16341         546 :                 if(getenv("SMB_CONF_PATH")) {
   16342         546 :                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
   16343             :                 }
   16344             :         }
   16345         546 :         lp_load_global(get_dyn_CONFIGFILE());
   16346         546 :         load_interfaces();
   16347             : 
   16348         546 :         if (argc < 2) {
   16349           0 :                 usage();
   16350             :         }
   16351             : 
   16352       11065 :         for(p = argv[1]; *p; p++)
   16353       10519 :           if(*p == '\\')
   16354           0 :             *p = '/';
   16355             : 
   16356         546 :         if (strncmp(argv[1], "//", 2)) {
   16357           0 :                 usage();
   16358             :         }
   16359             : 
   16360         546 :         fstrcpy(host, &argv[1][2]);
   16361         546 :         p = strchr_m(&host[2],'/');
   16362         546 :         if (!p) {
   16363           0 :                 usage();
   16364             :         }
   16365         546 :         *p = 0;
   16366         546 :         fstrcpy(share, p+1);
   16367             : 
   16368         546 :         fstrcpy(myname, get_myname(talloc_tos()));
   16369         546 :         if (!*myname) {
   16370           0 :                 fprintf(stderr, "Failed to get my hostname.\n");
   16371           0 :                 return 1;
   16372             :         }
   16373             : 
   16374         546 :         if (*username == 0 && getenv("LOGNAME")) {
   16375           0 :           fstrcpy(username,getenv("LOGNAME"));
   16376             :         }
   16377             : 
   16378         546 :         argc--;
   16379         546 :         argv++;
   16380             : 
   16381         546 :         fstrcpy(workgroup, lp_workgroup());
   16382             : 
   16383        1729 :         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
   16384        1774 :                != EOF) {
   16385        1228 :                 switch (opt) {
   16386           0 :                 case 'p':
   16387           0 :                         port_to_use = atoi(optarg);
   16388           0 :                         break;
   16389           0 :                 case 's':
   16390           0 :                         seed = atoi(optarg);
   16391           0 :                         break;
   16392           0 :                 case 'W':
   16393           0 :                         fstrcpy(workgroup,optarg);
   16394           0 :                         break;
   16395          33 :                 case 'm':
   16396          33 :                         lpcfg_set_cmdline(lp_ctx, "client max protocol", optarg);
   16397          33 :                         break;
   16398           0 :                 case 'N':
   16399           0 :                         torture_nprocs = atoi(optarg);
   16400           0 :                         break;
   16401           0 :                 case 'o':
   16402           0 :                         torture_numops = atoi(optarg);
   16403           0 :                         break;
   16404           0 :                 case 'd':
   16405           0 :                         lpcfg_set_cmdline(lp_ctx, "log level", optarg);
   16406           0 :                         break;
   16407           0 :                 case 'O':
   16408           0 :                         sockops = optarg;
   16409           0 :                         break;
   16410           0 :                 case 'L':
   16411           0 :                         use_oplocks = True;
   16412           0 :                         break;
   16413         463 :                 case 'l':
   16414         463 :                         local_path = optarg;
   16415         463 :                         break;
   16416           0 :                 case 'A':
   16417           0 :                         torture_showall = True;
   16418           0 :                         break;
   16419           0 :                 case 'n':
   16420           0 :                         fstrcpy(myname, optarg);
   16421           0 :                         break;
   16422           0 :                 case 'c':
   16423           0 :                         client_txt = optarg;
   16424           0 :                         break;
   16425         182 :                 case 'e':
   16426         182 :                         do_encrypt = true;
   16427         182 :                         break;
   16428           0 :                 case 'k':
   16429             : #ifdef HAVE_KRB5
   16430           0 :                         use_kerberos = True;
   16431             : #else
   16432             :                         d_printf("No kerberos support compiled in\n");
   16433             :                         exit(1);
   16434             : #endif
   16435           0 :                         break;
   16436         546 :                 case 'U':
   16437         546 :                         gotuser = 1;
   16438         546 :                         fstrcpy(username,optarg);
   16439         546 :                         p = strchr_m(username,'%');
   16440         546 :                         if (p) {
   16441         546 :                                 *p = 0;
   16442         546 :                                 fstrcpy(password, p+1);
   16443         546 :                                 gotpass = 1;
   16444             :                         }
   16445         501 :                         break;
   16446           0 :                 case 'b':
   16447           0 :                         fstrcpy(multishare_conn_fname, optarg);
   16448           0 :                         use_multishare_conn = True;
   16449           0 :                         break;
   16450           0 :                 case 'B':
   16451           0 :                         torture_blocksize = atoi(optarg);
   16452           0 :                         break;
   16453           4 :                 case 'f':
   16454           4 :                         test_filename = SMB_STRDUP(optarg);
   16455           4 :                         break;
   16456           0 :                 default:
   16457           0 :                         printf("Unknown option %c (%d)\n", (char)opt, opt);
   16458           0 :                         usage();
   16459             :                 }
   16460             :         }
   16461             : 
   16462         546 :         d_printf("using seed %d\n", seed);
   16463             : 
   16464         546 :         srandom(seed);
   16465             : 
   16466         546 :         if(use_kerberos && !gotuser) gotpass = True;
   16467             : 
   16468         546 :         while (!gotpass) {
   16469           0 :                 char pwd[256] = {0};
   16470           0 :                 int rc;
   16471             : 
   16472           0 :                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
   16473           0 :                 if (rc == 0) {
   16474           0 :                         fstrcpy(password, pwd);
   16475           0 :                         gotpass = 1;
   16476             :                 }
   16477             :         }
   16478             : 
   16479         546 :         printf("host=%s share=%s user=%s myname=%s\n", 
   16480             :                host, share, username, myname);
   16481             : 
   16482         546 :         torture_creds = cli_session_creds_init(frame,
   16483             :                                                username,
   16484             :                                                workgroup,
   16485             :                                                NULL, /* realm */
   16486             :                                                password,
   16487             :                                                use_kerberos,
   16488             :                                                false, /* fallback_after_kerberos */
   16489             :                                                false, /* use_ccache */
   16490             :                                                false); /* password_is_nt_hash */
   16491         546 :         if (torture_creds == NULL) {
   16492           0 :                 d_printf("cli_session_creds_init() failed.\n");
   16493           0 :                 exit(1);
   16494             :         }
   16495             : 
   16496         546 :         if (argc == optind) {
   16497           0 :                 correct = run_test("ALL");
   16498             :         } else {
   16499        1096 :                 for (i=optind;i<argc;i++) {
   16500         546 :                         if (!run_test(argv[i])) {
   16501          16 :                                 correct = False;
   16502             :                         }
   16503             :                 }
   16504             :         }
   16505             : 
   16506         550 :         TALLOC_FREE(frame);
   16507             : 
   16508         550 :         if (correct) {
   16509         485 :                 return(0);
   16510             :         } else {
   16511          16 :                 return(1);
   16512             :         }
   16513             : }

Generated by: LCOV version 1.14