LCOV - code coverage report
Current view: top level - source3/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 2229 7540 29.6 %
Date: 2024-06-13 04:01:37 Functions: 95 238 39.9 %

          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/param/param.h"
      52             : #include "auth/gensec/gensec.h"
      53             : #include "lib/util/string_wrappers.h"
      54             : #include "source3/lib/substitute.h"
      55             : 
      56             : #include <gnutls/gnutls.h>
      57             : #include <gnutls/crypto.h>
      58             : 
      59             : extern char *optarg;
      60             : extern int optind;
      61             : 
      62             : fstring host, workgroup, share, password, username, myname;
      63             : struct cli_credentials *torture_creds;
      64             : static const char *sockops="TCP_NODELAY";
      65             : int torture_nprocs=1;
      66             : static int port_to_use=0;
      67             : int torture_numops=100;
      68             : int torture_blocksize=1024*1024;
      69             : static int procnum; /* records process count number when forking */
      70             : static struct cli_state *current_cli;
      71             : static fstring randomfname;
      72             : static bool use_oplocks;
      73             : static bool use_level_II_oplocks;
      74             : static const char *client_txt = "client_oplocks.txt";
      75             : static bool disable_spnego;
      76             : static bool use_kerberos;
      77             : static bool force_dos_errors;
      78             : static fstring multishare_conn_fname;
      79             : static bool use_multishare_conn = False;
      80             : static bool do_encrypt;
      81             : static const char *local_path = NULL;
      82             : static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
      83             : char *test_filename;
      84             : 
      85             : bool torture_showall = False;
      86             : 
      87             : static double create_procs(bool (*fn)(int), bool *result);
      88             : 
      89             : /********************************************************************
      90             :  Ensure a connection is encrypted.
      91             : ********************************************************************/
      92             : 
      93           0 : static bool force_cli_encryption(struct cli_state *c,
      94             :                         const char *sharename)
      95             : {
      96             :         uint16_t major, minor;
      97             :         uint32_t caplow, caphigh;
      98             :         NTSTATUS status;
      99             : 
     100           0 :         if (!SERVER_HAS_UNIX_CIFS(c)) {
     101           0 :                 d_printf("Encryption required and "
     102             :                         "server that doesn't support "
     103             :                         "UNIX extensions - failing connect\n");
     104           0 :                         return false;
     105             :         }
     106             : 
     107           0 :         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
     108             :                                              &caphigh);
     109           0 :         if (!NT_STATUS_IS_OK(status)) {
     110           0 :                 d_printf("Encryption required and "
     111             :                         "can't get UNIX CIFS extensions "
     112             :                         "version from server: %s\n", nt_errstr(status));
     113           0 :                 return false;
     114             :         }
     115             : 
     116           0 :         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
     117           0 :                 d_printf("Encryption required and "
     118             :                         "share %s doesn't support "
     119             :                         "encryption.\n", sharename);
     120           0 :                 return false;
     121             :         }
     122             : 
     123           0 :         status = cli_smb1_setup_encryption(c, torture_creds);
     124           0 :         if (!NT_STATUS_IS_OK(status)) {
     125           0 :                 d_printf("Encryption required and "
     126             :                         "setup failed with error %s.\n",
     127             :                         nt_errstr(status));
     128           0 :                 return false;
     129             :         }
     130             : 
     131           0 :         return true;
     132             : }
     133             : 
     134             : 
     135           8 : static struct cli_state *open_nbt_connection(void)
     136             : {
     137             :         struct cli_state *c;
     138             :         NTSTATUS status;
     139           8 :         int flags = 0;
     140             : 
     141           8 :         if (disable_spnego) {
     142           0 :                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
     143             :         }
     144             : 
     145           8 :         if (use_oplocks) {
     146           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     147             :         }
     148             : 
     149           8 :         if (use_level_II_oplocks) {
     150           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     151             :         }
     152             : 
     153           8 :         if (force_dos_errors) {
     154           0 :                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
     155             :         }
     156             : 
     157           8 :         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
     158             :                                 signing_state, flags, &c);
     159           8 :         if (!NT_STATUS_IS_OK(status)) {
     160           0 :                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
     161           0 :                 return NULL;
     162             :         }
     163             : 
     164           8 :         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
     165             : 
     166           8 :         return c;
     167             : }
     168             : 
     169             : /****************************************************************************
     170             :  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
     171             : ****************************************************************************/
     172             : 
     173           0 : static bool cli_bad_session_request(int fd,
     174             :                          struct nmb_name *calling, struct nmb_name *called)
     175             : {
     176             :         TALLOC_CTX *frame;
     177             :         uint8_t len_buf[4];
     178             :         struct iovec iov[3];
     179             :         ssize_t len;
     180             :         uint8_t *inbuf;
     181             :         int err;
     182           0 :         bool ret = false;
     183             :         uint8_t message_type;
     184             :         uint8_t error;
     185             :         struct tevent_context *ev;
     186             :         struct tevent_req *req;
     187             : 
     188           0 :         frame = talloc_stackframe();
     189             : 
     190           0 :         iov[0].iov_base = len_buf;
     191           0 :         iov[0].iov_len  = sizeof(len_buf);
     192             : 
     193             :         /* put in the destination name */
     194             : 
     195           0 :         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
     196           0 :                                       called->name_type);
     197           0 :         if (iov[1].iov_base == NULL) {
     198           0 :                 goto fail;
     199             :         }
     200           0 :         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
     201           0 :                                   talloc_get_size(iov[1].iov_base));
     202             : 
     203             :         /* and my name */
     204             : 
     205           0 :         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
     206           0 :                                       calling->name_type);
     207           0 :         if (iov[2].iov_base == NULL) {
     208           0 :                 goto fail;
     209             :         }
     210           0 :         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
     211           0 :                                   talloc_get_size(iov[2].iov_base));
     212             : 
     213             :         /* Deliberately corrupt the name len (first byte) */
     214           0 :         *((uint8_t *)iov[2].iov_base) = 100;
     215             : 
     216             :         /* send a session request (RFC 1002) */
     217             :         /* setup the packet length
     218             :          * Remove four bytes from the length count, since the length
     219             :          * field in the NBT Session Service header counts the number
     220             :          * of bytes which follow.  The cli_send_smb() function knows
     221             :          * about this and accounts for those four bytes.
     222             :          * CRH.
     223             :          */
     224             : 
     225           0 :         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
     226           0 :         SCVAL(len_buf,0,0x81);
     227             : 
     228           0 :         len = write_data_iov(fd, iov, 3);
     229           0 :         if (len == -1) {
     230           0 :                 goto fail;
     231             :         }
     232             : 
     233           0 :         ev = samba_tevent_context_init(frame);
     234           0 :         if (ev == NULL) {
     235           0 :                 goto fail;
     236             :         }
     237           0 :         req = read_smb_send(frame, ev, fd);
     238           0 :         if (req == NULL) {
     239           0 :                 goto fail;
     240             :         }
     241           0 :         if (!tevent_req_poll(req, ev)) {
     242           0 :                 goto fail;
     243             :         }
     244           0 :         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
     245           0 :         if (len == -1) {
     246           0 :                 errno = err;
     247           0 :                 goto fail;
     248             :         }
     249           0 :         TALLOC_FREE(ev);
     250             : 
     251           0 :         message_type = CVAL(inbuf, 0);
     252           0 :         if (message_type != 0x83) {
     253           0 :                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
     254             :                           message_type);
     255           0 :                 goto fail;
     256             :         }
     257             : 
     258           0 :         if (smb_len(inbuf) != 1) {
     259           0 :                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
     260           0 :                           (int)smb_len(inbuf));
     261           0 :                 goto fail;
     262             :         }
     263             : 
     264           0 :         error = CVAL(inbuf, 4);
     265           0 :         if (error !=  0x82) {
     266           0 :                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
     267             :                           (int)error);
     268           0 :                 goto fail;
     269             :         }
     270             : 
     271           0 :         ret = true;
     272           0 : fail:
     273           0 :         TALLOC_FREE(frame);
     274           0 :         return ret;
     275             : }
     276             : 
     277             : /* Insert a NULL at the first separator of the given path and return a pointer
     278             :  * to the remainder of the string.
     279             :  */
     280             : static char *
     281           0 : terminate_path_at_separator(char * path)
     282             : {
     283             :         char * p;
     284             : 
     285           0 :         if (!path) {
     286           0 :                 return NULL;
     287             :         }
     288             : 
     289           0 :         if ((p = strchr_m(path, '/'))) {
     290           0 :                 *p = '\0';
     291           0 :                 return p + 1;
     292             :         }
     293             : 
     294           0 :         if ((p = strchr_m(path, '\\'))) {
     295           0 :                 *p = '\0';
     296           0 :                 return p + 1;
     297             :         }
     298             : 
     299             :         /* No separator. */
     300           0 :         return NULL;
     301             : }
     302             : 
     303             : /*
     304             :   parse a //server/share type UNC name
     305             : */
     306           0 : bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     307             :                       char **hostname, char **sharename)
     308             : {
     309             :         char *p;
     310             : 
     311           0 :         *hostname = *sharename = NULL;
     312             : 
     313           0 :         if (strncmp(unc_name, "\\\\", 2) &&
     314           0 :             strncmp(unc_name, "//", 2)) {
     315           0 :                 return False;
     316             :         }
     317             : 
     318           0 :         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
     319           0 :         p = terminate_path_at_separator(*hostname);
     320             : 
     321           0 :         if (p && *p) {
     322           0 :                 *sharename = talloc_strdup(mem_ctx, p);
     323           0 :                 terminate_path_at_separator(*sharename);
     324             :         }
     325             : 
     326           0 :         if (*hostname && *sharename) {
     327           0 :                 return True;
     328             :         }
     329             : 
     330           0 :         TALLOC_FREE(*hostname);
     331           0 :         TALLOC_FREE(*sharename);
     332           0 :         return False;
     333             : }
     334             : 
     335          58 : static bool torture_open_connection_share(struct cli_state **c,
     336             :                                    const char *hostname, 
     337             :                                    const char *sharename,
     338             :                                    int flags)
     339             : {
     340             :         NTSTATUS status;
     341             : 
     342          58 :         status = cli_full_connection_creds(c,
     343             :                                            myname,
     344             :                                            hostname,
     345             :                                            NULL, /* dest_ss */
     346             :                                            port_to_use,
     347             :                                            sharename,
     348             :                                            "?????",
     349             :                                            torture_creds,
     350             :                                            flags);
     351          58 :         if (!NT_STATUS_IS_OK(status)) {
     352           2 :                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
     353             :                         hostname, sharename, port_to_use, nt_errstr(status));
     354           2 :                 return False;
     355             :         }
     356             : 
     357          56 :         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
     358             : 
     359          56 :         if (do_encrypt) {
     360           0 :                 return force_cli_encryption(*c,
     361             :                                         sharename);
     362             :         }
     363          56 :         return True;
     364             : }
     365             : 
     366          58 : bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
     367             : {
     368          58 :         char **unc_list = NULL;
     369          58 :         int num_unc_names = 0;
     370             :         bool result;
     371             : 
     372          58 :         if (use_multishare_conn==True) {
     373             :                 char *h, *s;
     374           0 :                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
     375           0 :                 if (!unc_list || num_unc_names <= 0) {
     376           0 :                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
     377           0 :                         exit(1);
     378             :                 }
     379             : 
     380           0 :                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
     381             :                                       NULL, &h, &s)) {
     382           0 :                         printf("Failed to parse UNC name %s\n",
     383           0 :                                unc_list[conn_index % num_unc_names]);
     384           0 :                         TALLOC_FREE(unc_list);
     385           0 :                         exit(1);
     386             :                 }
     387             : 
     388           0 :                 result = torture_open_connection_share(c, h, s, flags);
     389             : 
     390             :                 /* h, s were copied earlier */
     391           0 :                 TALLOC_FREE(unc_list);
     392           0 :                 return result;
     393             :         }
     394             : 
     395          58 :         return torture_open_connection_share(c, host, share, flags);
     396             : }
     397             : 
     398          58 : bool torture_open_connection(struct cli_state **c, int conn_index)
     399             : {
     400          58 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
     401             : 
     402          58 :         if (use_oplocks) {
     403           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     404             :         }
     405          58 :         if (use_level_II_oplocks) {
     406           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     407             :         }
     408             : 
     409          58 :         return torture_open_connection_flags(c, conn_index, flags);
     410             : }
     411             : 
     412           6 : bool torture_init_connection(struct cli_state **pcli)
     413             : {
     414             :         struct cli_state *cli;
     415             : 
     416           6 :         cli = open_nbt_connection();
     417           6 :         if (cli == NULL) {
     418           0 :                 return false;
     419             :         }
     420             : 
     421           6 :         *pcli = cli;
     422           6 :         return true;
     423             : }
     424             : 
     425           1 : bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
     426             : {
     427           1 :         uint16_t old_vuid = cli_state_get_uid(cli);
     428             :         NTSTATUS status;
     429             :         bool ret;
     430             : 
     431           1 :         cli_state_set_uid(cli, 0);
     432           1 :         status = cli_session_setup_creds(cli, torture_creds);
     433           1 :         ret = NT_STATUS_IS_OK(status);
     434           1 :         *new_vuid = cli_state_get_uid(cli);
     435           1 :         cli_state_set_uid(cli, old_vuid);
     436           1 :         return ret;
     437             : }
     438             : 
     439             : 
     440          49 : bool torture_close_connection(struct cli_state *c)
     441             : {
     442          49 :         bool ret = True;
     443             :         NTSTATUS status;
     444             : 
     445          49 :         status = cli_tdis(c);
     446          49 :         if (!NT_STATUS_IS_OK(status)) {
     447           1 :                 printf("tdis failed (%s)\n", nt_errstr(status));
     448           1 :                 ret = False;
     449             :         }
     450             : 
     451          49 :         cli_shutdown(c);
     452             : 
     453          49 :         return ret;
     454             : }
     455             : 
     456           0 : void torture_conn_set_sockopt(struct cli_state *cli)
     457             : {
     458           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     459           0 : }
     460             : 
     461           6 : static NTSTATUS torture_delete_fn(struct file_info *finfo,
     462             :                                   const char *pattern,
     463             :                                   void *state)
     464             : {
     465             :         NTSTATUS status;
     466           6 :         char *filename = NULL;
     467           6 :         char *dirname = NULL;
     468           6 :         char *p = NULL;
     469           6 :         TALLOC_CTX *frame = talloc_stackframe();
     470           6 :         struct cli_state *cli = (struct cli_state *)state;
     471             : 
     472           6 :         if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
     473           4 :                 TALLOC_FREE(frame);
     474           4 :                 return NT_STATUS_OK;
     475             :         }
     476             : 
     477           2 :         dirname = talloc_strdup(frame, pattern);
     478           2 :         if (dirname == NULL) {
     479           0 :                 TALLOC_FREE(frame);
     480           0 :                 return NT_STATUS_NO_MEMORY;
     481             :         }
     482           2 :         p = strrchr_m(dirname, '\\');
     483           2 :         if (p != NULL) {
     484             :                 /* Remove the terminating '\' */
     485           2 :                 *p = '\0';
     486             :         }
     487           2 :         if (dirname[0] != '\0') {
     488           2 :                 filename = talloc_asprintf(frame,
     489             :                                            "%s\\%s",
     490             :                                            dirname,
     491             :                                            finfo->name);
     492             :         } else {
     493           0 :                 filename = talloc_asprintf(frame,
     494             :                                            "%s",
     495             :                                            finfo->name);
     496             :         }
     497           2 :         if (filename == NULL) {
     498           0 :                 TALLOC_FREE(frame);
     499           0 :                 return NT_STATUS_NO_MEMORY;
     500             :         }
     501           2 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     502           1 :                 char *subdirname = talloc_asprintf(frame,
     503             :                                                    "%s\\*",
     504             :                                                    filename);
     505           1 :                 if (subdirname == NULL) {
     506           0 :                         TALLOC_FREE(frame);
     507           0 :                         return NT_STATUS_NO_MEMORY;
     508             :                 }
     509           1 :                 status = cli_list(cli,
     510             :                                   subdirname,
     511             :                                   FILE_ATTRIBUTE_DIRECTORY |
     512             :                                           FILE_ATTRIBUTE_HIDDEN |
     513             :                                           FILE_ATTRIBUTE_SYSTEM,
     514             :                                   torture_delete_fn,
     515             :                                   cli);
     516           1 :                 if (!NT_STATUS_IS_OK(status)) {
     517           0 :                         printf("torture_delete_fn: cli_list "
     518             :                                 "of %s failed (%s)\n",
     519             :                                 subdirname,
     520             :                                 nt_errstr(status));
     521           0 :                         TALLOC_FREE(frame);
     522           0 :                         return status;
     523             :                 }
     524           1 :                 status = cli_rmdir(cli, filename);
     525             :         } else {
     526           1 :                 status = cli_unlink(cli,
     527             :                                     filename,
     528             :                                     FILE_ATTRIBUTE_SYSTEM |
     529             :                                         FILE_ATTRIBUTE_HIDDEN);
     530             :         }
     531           2 :         if (!NT_STATUS_IS_OK(status)) {
     532           0 :                 if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     533           0 :                         printf("torture_delete_fn: cli_rmdir"
     534             :                                 " of %s failed (%s)\n",
     535             :                                 filename,
     536             :                                 nt_errstr(status));
     537             :                 } else {
     538           0 :                         printf("torture_delete_fn: cli_unlink"
     539             :                                 " of %s failed (%s)\n",
     540             :                                 filename,
     541             :                                 nt_errstr(status));
     542             :                 }
     543             :         }
     544           2 :         TALLOC_FREE(frame);
     545           2 :         return status;
     546             : }
     547             : 
     548           2 : void torture_deltree(struct cli_state *cli, const char *dname)
     549             : {
     550           2 :         char *mask = NULL;
     551             :         NTSTATUS status;
     552             : 
     553             :         /* It might be a file */
     554           2 :         (void)cli_unlink(cli,
     555             :                          dname,
     556             :                          FILE_ATTRIBUTE_SYSTEM |
     557             :                                 FILE_ATTRIBUTE_HIDDEN);
     558             : 
     559           2 :         mask = talloc_asprintf(cli,
     560             :                                "%s\\*",
     561             :                                dname);
     562           2 :         if (mask == NULL) {
     563           0 :                 printf("torture_deltree: talloc_asprintf failed\n");
     564           0 :                 return;
     565             :         }
     566             : 
     567           2 :         status = cli_list(cli,
     568             :                         mask,
     569             :                         FILE_ATTRIBUTE_DIRECTORY |
     570             :                                 FILE_ATTRIBUTE_HIDDEN|
     571             :                                 FILE_ATTRIBUTE_SYSTEM,
     572             :                         torture_delete_fn,
     573             :                         cli);
     574           2 :         if (!NT_STATUS_IS_OK(status)) {
     575           1 :                 printf("torture_deltree: cli_list of %s failed (%s)\n",
     576             :                         mask,
     577             :                         nt_errstr(status));
     578             :         }
     579           2 :         TALLOC_FREE(mask);
     580           2 :         status = cli_rmdir(cli, dname);
     581           2 :         if (!NT_STATUS_IS_OK(status)) {
     582           1 :                 printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
     583             :                         dname,
     584             :                         nt_errstr(status));
     585             :         }
     586             : }
     587             : 
     588             : /* check if the server produced the expected dos or nt error code */
     589           9 : static bool check_both_error(int line, NTSTATUS status,
     590             :                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     591             : {
     592           9 :         if (NT_STATUS_IS_DOS(status)) {
     593             :                 uint8_t cclass;
     594             :                 uint32_t num;
     595             : 
     596             :                 /* Check DOS error */
     597           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     598           0 :                 num = NT_STATUS_DOS_CODE(status);
     599             : 
     600           0 :                 if (eclass != cclass || ecode != num) {
     601           0 :                         printf("unexpected error code class=%d code=%d\n",
     602             :                                (int)cclass, (int)num);
     603           0 :                         printf(" expected %d/%d %s (line=%d)\n",
     604             :                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
     605           0 :                         return false;
     606             :                 }
     607             :         } else {
     608             :                 /* Check NT error */
     609           9 :                 if (!NT_STATUS_EQUAL(nterr, status)) {
     610           0 :                         printf("unexpected error code %s\n",
     611             :                                 nt_errstr(status));
     612           0 :                         printf(" expected %s (line=%d)\n",
     613             :                                 nt_errstr(nterr), line);
     614           0 :                         return false;
     615             :                 }
     616             :         }
     617             : 
     618           9 :         return true;
     619             : }
     620             : 
     621             : 
     622             : /* check if the server produced the expected error code */
     623           6 : static bool check_error(int line, NTSTATUS status,
     624             :                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     625             : {
     626           6 :         if (NT_STATUS_IS_DOS(status)) {
     627             :                 uint8_t cclass;
     628             :                 uint32_t num;
     629             : 
     630             :                 /* Check DOS error */
     631             : 
     632           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     633           0 :                 num = NT_STATUS_DOS_CODE(status);
     634             : 
     635           0 :                 if (eclass != cclass || ecode != num) {
     636           0 :                         printf("unexpected error code class=%d code=%d\n", 
     637             :                                (int)cclass, (int)num);
     638           0 :                         printf(" expected %d/%d %s (line=%d)\n", 
     639             :                                (int)eclass, (int)ecode, nt_errstr(nterr),
     640             :                                line);
     641           0 :                         return False;
     642             :                 }
     643             : 
     644             :         } else {
     645             :                 /* Check NT error */
     646             : 
     647           6 :                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
     648           1 :                         printf("unexpected error code %s\n",
     649             :                                nt_errstr(status));
     650           1 :                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
     651             :                                line);
     652           1 :                         return False;
     653             :                 }
     654             :         }
     655             : 
     656           5 :         return True;
     657             : }
     658             : 
     659             : 
     660           0 : static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
     661             : {
     662             :         NTSTATUS status;
     663             : 
     664           0 :         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     665             : 
     666           0 :         while (!NT_STATUS_IS_OK(status)) {
     667           0 :                 if (!check_both_error(__LINE__, status, ERRDOS,
     668           0 :                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
     669           0 :                         return false;
     670             :                 }
     671             : 
     672           0 :                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     673             :         }
     674             : 
     675           0 :         return true;
     676             : }
     677             : 
     678             : 
     679           0 : static bool rw_torture(struct cli_state *c)
     680             : {
     681           0 :         const char *lockfname = "\\torture.lck";
     682             :         fstring fname;
     683             :         uint16_t fnum;
     684             :         uint16_t fnum2;
     685           0 :         pid_t pid2, pid = getpid();
     686             :         int i, j;
     687             :         char buf[1024];
     688           0 :         bool correct = True;
     689           0 :         size_t nread = 0;
     690             :         NTSTATUS status;
     691             : 
     692           0 :         memset(buf, '\0', sizeof(buf));
     693             : 
     694           0 :         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
     695             :                          DENY_NONE, &fnum2);
     696           0 :         if (!NT_STATUS_IS_OK(status)) {
     697           0 :                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
     698             :         }
     699           0 :         if (!NT_STATUS_IS_OK(status)) {
     700           0 :                 printf("open of %s failed (%s)\n",
     701             :                        lockfname, nt_errstr(status));
     702           0 :                 return False;
     703             :         }
     704             : 
     705           0 :         for (i=0;i<torture_numops;i++) {
     706           0 :                 unsigned n = (unsigned)sys_random()%10;
     707             : 
     708           0 :                 if (i % 10 == 0) {
     709           0 :                         printf("%d\r", i); fflush(stdout);
     710             :                 }
     711           0 :                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
     712             : 
     713           0 :                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
     714           0 :                         return False;
     715             :                 }
     716             : 
     717           0 :                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
     718             :                                   DENY_ALL, &fnum);
     719           0 :                 if (!NT_STATUS_IS_OK(status)) {
     720           0 :                         printf("open failed (%s)\n", nt_errstr(status));
     721           0 :                         correct = False;
     722           0 :                         break;
     723             :                 }
     724             : 
     725           0 :                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
     726             :                                       sizeof(pid), NULL);
     727           0 :                 if (!NT_STATUS_IS_OK(status)) {
     728           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     729           0 :                         correct = False;
     730             :                 }
     731             : 
     732           0 :                 for (j=0;j<50;j++) {
     733           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
     734           0 :                                               sizeof(pid)+(j*sizeof(buf)),
     735             :                                               sizeof(buf), NULL);
     736           0 :                         if (!NT_STATUS_IS_OK(status)) {
     737           0 :                                 printf("write failed (%s)\n",
     738             :                                        nt_errstr(status));
     739           0 :                                 correct = False;
     740             :                         }
     741             :                 }
     742             : 
     743           0 :                 pid2 = 0;
     744             : 
     745           0 :                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
     746             :                                   &nread);
     747           0 :                 if (!NT_STATUS_IS_OK(status)) {
     748           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     749           0 :                         correct = false;
     750           0 :                 } else if (nread != sizeof(pid)) {
     751           0 :                         printf("read/write compare failed: "
     752             :                                "recv %ld req %ld\n", (unsigned long)nread,
     753             :                                (unsigned long)sizeof(pid));
     754           0 :                         correct = false;
     755             :                 }
     756             : 
     757           0 :                 if (pid2 != pid) {
     758           0 :                         printf("data corruption!\n");
     759           0 :                         correct = False;
     760             :                 }
     761             : 
     762           0 :                 status = cli_close(c, fnum);
     763           0 :                 if (!NT_STATUS_IS_OK(status)) {
     764           0 :                         printf("close failed (%s)\n", nt_errstr(status));
     765           0 :                         correct = False;
     766             :                 }
     767             : 
     768           0 :                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     769           0 :                 if (!NT_STATUS_IS_OK(status)) {
     770           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
     771           0 :                         correct = False;
     772             :                 }
     773             : 
     774           0 :                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
     775           0 :                 if (!NT_STATUS_IS_OK(status)) {
     776           0 :                         printf("unlock failed (%s)\n", nt_errstr(status));
     777           0 :                         correct = False;
     778             :                 }
     779             :         }
     780             : 
     781           0 :         cli_close(c, fnum2);
     782           0 :         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     783             : 
     784           0 :         printf("%d\n", i);
     785             : 
     786           0 :         return correct;
     787             : }
     788             : 
     789           0 : static bool run_torture(int dummy)
     790             : {
     791             :         struct cli_state *cli;
     792             :         bool ret;
     793             : 
     794           0 :         cli = current_cli;
     795             : 
     796           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     797             : 
     798           0 :         ret = rw_torture(cli);
     799             : 
     800           0 :         if (!torture_close_connection(cli)) {
     801           0 :                 ret = False;
     802             :         }
     803             : 
     804           0 :         return ret;
     805             : }
     806             : 
     807           0 : static bool rw_torture3(struct cli_state *c, char *lockfname)
     808             : {
     809           0 :         uint16_t fnum = (uint16_t)-1;
     810           0 :         unsigned int i = 0;
     811             :         char buf[131072];
     812             :         char buf_rd[131072];
     813             :         unsigned count;
     814           0 :         unsigned countprev = 0;
     815           0 :         size_t sent = 0;
     816           0 :         bool correct = True;
     817           0 :         NTSTATUS status = NT_STATUS_OK;
     818             : 
     819           0 :         srandom(1);
     820           0 :         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
     821             :         {
     822           0 :                 SIVAL(buf, i, sys_random());
     823             :         }
     824             : 
     825           0 :         if (procnum == 0)
     826             :         {
     827           0 :                 status = cli_unlink(
     828             :                         c, lockfname,
     829             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     830           0 :                 if (!NT_STATUS_IS_OK(status)) {
     831           0 :                         printf("unlink failed (%s) (normal, this file should "
     832             :                                "not exist)\n", nt_errstr(status));
     833             :                 }
     834             : 
     835           0 :                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     836             :                                   DENY_NONE, &fnum);
     837           0 :                 if (!NT_STATUS_IS_OK(status)) {
     838           0 :                         printf("first open read/write of %s failed (%s)\n",
     839             :                                         lockfname, nt_errstr(status));
     840           0 :                         return False;
     841             :                 }
     842             :         }
     843             :         else
     844             :         {
     845           0 :                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
     846             :                 {
     847           0 :                         status = cli_openx(c, lockfname, O_RDONLY, 
     848             :                                          DENY_NONE, &fnum);
     849           0 :                         if (NT_STATUS_IS_OK(status)) {
     850           0 :                                 break;
     851             :                         }
     852           0 :                         smb_msleep(10);
     853             :                 }
     854           0 :                 if (!NT_STATUS_IS_OK(status)) {
     855           0 :                         printf("second open read-only of %s failed (%s)\n",
     856             :                                         lockfname, nt_errstr(status));
     857           0 :                         return False;
     858             :                 }
     859             :         }
     860             : 
     861           0 :         i = 0;
     862           0 :         for (count = 0; count < sizeof(buf); count += sent)
     863             :         {
     864           0 :                 if (count >= countprev) {
     865           0 :                         printf("%d %8d\r", i, count);
     866           0 :                         fflush(stdout);
     867           0 :                         i++;
     868           0 :                         countprev += (sizeof(buf) / 20);
     869             :                 }
     870             : 
     871           0 :                 if (procnum == 0)
     872             :                 {
     873           0 :                         sent = ((unsigned)sys_random()%(20))+ 1;
     874           0 :                         if (sent > sizeof(buf) - count)
     875             :                         {
     876           0 :                                 sent = sizeof(buf) - count;
     877             :                         }
     878             : 
     879           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
     880             :                                               count, sent, NULL);
     881           0 :                         if (!NT_STATUS_IS_OK(status)) {
     882           0 :                                 printf("write failed (%s)\n",
     883             :                                        nt_errstr(status));
     884           0 :                                 correct = False;
     885             :                         }
     886             :                 }
     887             :                 else
     888             :                 {
     889           0 :                         status = cli_read(c, fnum, buf_rd+count, count,
     890             :                                           sizeof(buf)-count, &sent);
     891           0 :                         if(!NT_STATUS_IS_OK(status)) {
     892           0 :                                 printf("read failed offset:%d size:%ld (%s)\n",
     893             :                                        count, (unsigned long)sizeof(buf)-count,
     894             :                                        nt_errstr(status));
     895           0 :                                 correct = False;
     896           0 :                                 sent = 0;
     897           0 :                         } else if (sent > 0) {
     898           0 :                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
     899             :                                 {
     900           0 :                                         printf("read/write compare failed\n");
     901           0 :                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
     902           0 :                                         correct = False;
     903           0 :                                         break;
     904             :                                 }
     905             :                         }
     906             :                 }
     907             : 
     908             :         }
     909             : 
     910           0 :         status = cli_close(c, fnum);
     911           0 :         if (!NT_STATUS_IS_OK(status)) {
     912           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     913           0 :                 correct = False;
     914             :         }
     915             : 
     916           0 :         return correct;
     917             : }
     918             : 
     919           2 : static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     920             : {
     921           2 :         const char *lockfname = "\\torture2.lck";
     922             :         uint16_t fnum1;
     923             :         uint16_t fnum2;
     924             :         int i;
     925             :         char buf[131072];
     926             :         char buf_rd[131072];
     927           2 :         bool correct = True;
     928             :         size_t bytes_read;
     929             :         NTSTATUS status;
     930             : 
     931           2 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     932           2 :         if (!NT_STATUS_IS_OK(status)) {
     933           2 :                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
     934             :         }
     935             : 
     936           2 :         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     937             :                           DENY_NONE, &fnum1);
     938           2 :         if (!NT_STATUS_IS_OK(status)) {
     939           0 :                 printf("first open read/write of %s failed (%s)\n",
     940             :                                 lockfname, nt_errstr(status));
     941           0 :                 return False;
     942             :         }
     943             : 
     944           2 :         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
     945           2 :         if (!NT_STATUS_IS_OK(status)) {
     946           0 :                 printf("second open read-only of %s failed (%s)\n",
     947             :                                 lockfname, nt_errstr(status));
     948           0 :                 cli_close(c1, fnum1);
     949           0 :                 return False;
     950             :         }
     951             : 
     952         202 :         for (i = 0; i < torture_numops; i++)
     953             :         {
     954         200 :                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
     955         200 :                 if (i % 10 == 0) {
     956          20 :                         printf("%d\r", i); fflush(stdout);
     957             :                 }
     958             : 
     959         200 :                 generate_random_buffer((unsigned char *)buf, buf_size);
     960             : 
     961         200 :                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
     962             :                                       buf_size, NULL);
     963         200 :                 if (!NT_STATUS_IS_OK(status)) {
     964           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     965           0 :                         correct = False;
     966           0 :                         break;
     967             :                 }
     968             : 
     969         200 :                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
     970         200 :                 if(!NT_STATUS_IS_OK(status)) {
     971           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     972           0 :                         correct = false;
     973           0 :                         break;
     974         200 :                 } else if (bytes_read != buf_size) {
     975           0 :                         printf("read failed\n");
     976           0 :                         printf("read %ld, expected %ld\n",
     977             :                                (unsigned long)bytes_read,
     978             :                                (unsigned long)buf_size); 
     979           0 :                         correct = False;
     980           0 :                         break;
     981             :                 }
     982             : 
     983         200 :                 if (memcmp(buf_rd, buf, buf_size) != 0)
     984             :                 {
     985           0 :                         printf("read/write compare failed\n");
     986           0 :                         correct = False;
     987           0 :                         break;
     988             :                 }
     989             :         }
     990             : 
     991           2 :         status = cli_close(c2, fnum2);
     992           2 :         if (!NT_STATUS_IS_OK(status)) {
     993           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     994           0 :                 correct = False;
     995             :         }
     996             : 
     997           2 :         status = cli_close(c1, fnum1);
     998           2 :         if (!NT_STATUS_IS_OK(status)) {
     999           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1000           0 :                 correct = False;
    1001             :         }
    1002             : 
    1003           2 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1004           2 :         if (!NT_STATUS_IS_OK(status)) {
    1005           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1006           0 :                 correct = False;
    1007             :         }
    1008             : 
    1009           2 :         return correct;
    1010             : }
    1011             : 
    1012           1 : static bool run_readwritetest(int dummy)
    1013             : {
    1014             :         struct cli_state *cli1, *cli2;
    1015           1 :         bool test1, test2 = False;
    1016             : 
    1017           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1018           0 :                 return False;
    1019             :         }
    1020           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1021           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1022             : 
    1023           1 :         printf("starting readwritetest\n");
    1024             : 
    1025           1 :         test1 = rw_torture2(cli1, cli2);
    1026           1 :         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
    1027             : 
    1028           1 :         if (test1) {
    1029           1 :                 test2 = rw_torture2(cli1, cli1);
    1030           1 :                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
    1031             :         }
    1032             : 
    1033           1 :         if (!torture_close_connection(cli1)) {
    1034           0 :                 test1 = False;
    1035             :         }
    1036             : 
    1037           1 :         if (!torture_close_connection(cli2)) {
    1038           0 :                 test2 = False;
    1039             :         }
    1040             : 
    1041           1 :         return (test1 && test2);
    1042             : }
    1043             : 
    1044           0 : static bool run_readwritemulti(int dummy)
    1045             : {
    1046             :         struct cli_state *cli;
    1047             :         bool test;
    1048             : 
    1049           0 :         cli = current_cli;
    1050             : 
    1051           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1052             : 
    1053           0 :         printf("run_readwritemulti: fname %s\n", randomfname);
    1054           0 :         test = rw_torture3(cli, randomfname);
    1055             : 
    1056           0 :         if (!torture_close_connection(cli)) {
    1057           0 :                 test = False;
    1058             :         }
    1059             : 
    1060           0 :         return test;
    1061             : }
    1062             : 
    1063           2 : static bool run_readwritelarge_internal(void)
    1064             : {
    1065             :         static struct cli_state *cli1;
    1066             :         uint16_t fnum1;
    1067           2 :         const char *lockfname = "\\large.dat";
    1068             :         off_t fsize;
    1069             :         char buf[126*1024];
    1070           2 :         bool correct = True;
    1071             :         NTSTATUS status;
    1072             : 
    1073           2 :         if (!torture_open_connection(&cli1, 0)) {
    1074           0 :                 return False;
    1075             :         }
    1076           2 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1077           2 :         memset(buf,'\0',sizeof(buf));
    1078             : 
    1079           2 :         printf("starting readwritelarge_internal\n");
    1080             : 
    1081           2 :         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1082             : 
    1083           2 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1084             :                           DENY_NONE, &fnum1);
    1085           2 :         if (!NT_STATUS_IS_OK(status)) {
    1086           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1087           0 :                 return False;
    1088             :         }
    1089             : 
    1090           2 :         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
    1091             : 
    1092           2 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1093             :                                      NULL, NULL, NULL);
    1094           2 :         if (!NT_STATUS_IS_OK(status)) {
    1095           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1096           0 :                 correct = False;
    1097             :         }
    1098             : 
    1099           2 :         if (fsize == sizeof(buf))
    1100           2 :                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
    1101             :                        (unsigned long)fsize);
    1102             :         else {
    1103           0 :                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
    1104             :                        (unsigned long)fsize);
    1105           0 :                 correct = False;
    1106             :         }
    1107             : 
    1108           2 :         status = cli_close(cli1, fnum1);
    1109           2 :         if (!NT_STATUS_IS_OK(status)) {
    1110           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1111           0 :                 correct = False;
    1112             :         }
    1113             : 
    1114           2 :         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1115           2 :         if (!NT_STATUS_IS_OK(status)) {
    1116           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1117           0 :                 correct = False;
    1118             :         }
    1119             : 
    1120           2 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1121             :                           DENY_NONE, &fnum1);
    1122           2 :         if (!NT_STATUS_IS_OK(status)) {
    1123           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1124           0 :                 return False;
    1125             :         }
    1126             : 
    1127           2 :         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
    1128             : 
    1129           2 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1130             :                                      NULL, NULL, NULL);
    1131           2 :         if (!NT_STATUS_IS_OK(status)) {
    1132           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1133           0 :                 correct = False;
    1134             :         }
    1135             : 
    1136           2 :         if (fsize == sizeof(buf))
    1137           2 :                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
    1138             :                        (unsigned long)fsize);
    1139             :         else {
    1140           0 :                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
    1141             :                        (unsigned long)fsize);
    1142           0 :                 correct = False;
    1143             :         }
    1144             : 
    1145           2 :         status = cli_close(cli1, fnum1);
    1146           2 :         if (!NT_STATUS_IS_OK(status)) {
    1147           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1148           0 :                 correct = False;
    1149             :         }
    1150             : 
    1151           2 :         if (!torture_close_connection(cli1)) {
    1152           0 :                 correct = False;
    1153             :         }
    1154           2 :         return correct;
    1155             : }
    1156             : 
    1157           1 : static bool run_readwritelarge(int dummy)
    1158             : {
    1159           1 :         return run_readwritelarge_internal();
    1160             : }
    1161             : 
    1162           1 : static bool run_readwritelarge_signtest(int dummy)
    1163             : {
    1164             :         bool ret;
    1165           1 :         signing_state = SMB_SIGNING_REQUIRED;
    1166           1 :         ret = run_readwritelarge_internal();
    1167           1 :         signing_state = SMB_SIGNING_DEFAULT;
    1168           1 :         return ret;
    1169             : }
    1170             : 
    1171             : int line_count = 0;
    1172             : int nbio_id;
    1173             : 
    1174             : #define ival(s) strtol(s, NULL, 0)
    1175             : 
    1176             : /* run a test that simulates an approximate netbench client load */
    1177           0 : static bool run_netbench(int client)
    1178             : {
    1179             :         struct cli_state *cli;
    1180             :         int i;
    1181             :         char line[1024];
    1182             :         char cname[20];
    1183             :         FILE *f;
    1184             :         const char *params[20];
    1185           0 :         bool correct = True;
    1186             : 
    1187           0 :         cli = current_cli;
    1188             : 
    1189           0 :         nbio_id = client;
    1190             : 
    1191           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1192             : 
    1193           0 :         nb_setup(cli);
    1194             : 
    1195           0 :         slprintf(cname,sizeof(cname)-1, "client%d", client);
    1196             : 
    1197           0 :         f = fopen(client_txt, "r");
    1198             : 
    1199           0 :         if (!f) {
    1200           0 :                 perror(client_txt);
    1201           0 :                 return False;
    1202             :         }
    1203             : 
    1204           0 :         while (fgets(line, sizeof(line)-1, f)) {
    1205             :                 char *saveptr;
    1206           0 :                 line_count++;
    1207             : 
    1208           0 :                 line[strlen(line)-1] = 0;
    1209             : 
    1210             :                 /* printf("[%d] %s\n", line_count, line); */
    1211             : 
    1212           0 :                 all_string_sub(line,"client1", cname, sizeof(line));
    1213             : 
    1214             :                 /* parse the command parameters */
    1215           0 :                 params[0] = strtok_r(line, " ", &saveptr);
    1216           0 :                 i = 0;
    1217           0 :                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
    1218             : 
    1219           0 :                 params[i] = "";
    1220             : 
    1221           0 :                 if (i < 2) continue;
    1222             : 
    1223           0 :                 if (!strncmp(params[0],"SMB", 3)) {
    1224           0 :                         printf("ERROR: You are using a dbench 1 load file\n");
    1225           0 :                         exit(1);
    1226             :                 }
    1227             : 
    1228           0 :                 if (!strcmp(params[0],"NTCreateX")) {
    1229           0 :                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
    1230           0 :                                    ival(params[4]));
    1231           0 :                 } else if (!strcmp(params[0],"Close")) {
    1232           0 :                         nb_close(ival(params[1]));
    1233           0 :                 } else if (!strcmp(params[0],"Rename")) {
    1234           0 :                         nb_rename(params[1], params[2]);
    1235           0 :                 } else if (!strcmp(params[0],"Unlink")) {
    1236           0 :                         nb_unlink(params[1]);
    1237           0 :                 } else if (!strcmp(params[0],"Deltree")) {
    1238           0 :                         nb_deltree(params[1]);
    1239           0 :                 } else if (!strcmp(params[0],"Rmdir")) {
    1240           0 :                         nb_rmdir(params[1]);
    1241           0 :                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
    1242           0 :                         nb_qpathinfo(params[1]);
    1243           0 :                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
    1244           0 :                         nb_qfileinfo(ival(params[1]));
    1245           0 :                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
    1246           0 :                         nb_qfsinfo(ival(params[1]));
    1247           0 :                 } else if (!strcmp(params[0],"FIND_FIRST")) {
    1248           0 :                         nb_findfirst(params[1]);
    1249           0 :                 } else if (!strcmp(params[0],"WriteX")) {
    1250           0 :                         nb_writex(ival(params[1]), 
    1251           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1252           0 :                 } else if (!strcmp(params[0],"ReadX")) {
    1253           0 :                         nb_readx(ival(params[1]), 
    1254           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1255           0 :                 } else if (!strcmp(params[0],"Flush")) {
    1256           0 :                         nb_flush(ival(params[1]));
    1257             :                 } else {
    1258           0 :                         printf("Unknown operation %s\n", params[0]);
    1259           0 :                         exit(1);
    1260             :                 }
    1261             :         }
    1262           0 :         fclose(f);
    1263             : 
    1264           0 :         nb_cleanup();
    1265             : 
    1266           0 :         if (!torture_close_connection(cli)) {
    1267           0 :                 correct = False;
    1268             :         }
    1269             : 
    1270           0 :         return correct;
    1271             : }
    1272             : 
    1273             : 
    1274             : /* run a test that simulates an approximate netbench client load */
    1275           0 : static bool run_nbench(int dummy)
    1276             : {
    1277             :         double t;
    1278           0 :         bool correct = True;
    1279             : 
    1280           0 :         nbio_shmem(torture_nprocs);
    1281             : 
    1282           0 :         nbio_id = -1;
    1283             : 
    1284           0 :         signal(SIGALRM, nb_alarm);
    1285           0 :         alarm(1);
    1286           0 :         t = create_procs(run_netbench, &correct);
    1287           0 :         alarm(0);
    1288             : 
    1289           0 :         printf("\nThroughput %g MB/sec\n", 
    1290           0 :                1.0e-6 * nbio_total() / t);
    1291           0 :         return correct;
    1292             : }
    1293             : 
    1294             : 
    1295             : /*
    1296             :   This test checks for two things:
    1297             : 
    1298             :   1) correct support for retaining locks over a close (ie. the server
    1299             :      must not use posix semantics)
    1300             :   2) support for lock timeouts
    1301             :  */
    1302           1 : static bool run_locktest1(int dummy)
    1303             : {
    1304             :         struct cli_state *cli1, *cli2;
    1305           1 :         const char *fname = "\\lockt1.lck";
    1306             :         uint16_t fnum1, fnum2, fnum3;
    1307             :         time_t t1, t2;
    1308             :         unsigned lock_timeout;
    1309             :         NTSTATUS status;
    1310             : 
    1311           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1312           0 :                 return False;
    1313             :         }
    1314           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1315           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1316             : 
    1317           1 :         printf("starting locktest1\n");
    1318             : 
    1319           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1320             : 
    1321           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1322             :                           &fnum1);
    1323           1 :         if (!NT_STATUS_IS_OK(status)) {
    1324           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1325           0 :                 return False;
    1326             :         }
    1327             : 
    1328           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
    1329           1 :         if (!NT_STATUS_IS_OK(status)) {
    1330           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1331           0 :                 return False;
    1332             :         }
    1333             : 
    1334           1 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
    1335           1 :         if (!NT_STATUS_IS_OK(status)) {
    1336           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1337           0 :                 return False;
    1338             :         }
    1339             : 
    1340           1 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    1341           1 :         if (!NT_STATUS_IS_OK(status)) {
    1342           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1343           0 :                 return false;
    1344             :         }
    1345             : 
    1346           1 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1347           1 :         if (NT_STATUS_IS_OK(status)) {
    1348           0 :                 printf("lock2 succeeded! This is a locking bug\n");
    1349           0 :                 return false;
    1350             :         } else {
    1351           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1352           1 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1353           0 :                         return false;
    1354             :                 }
    1355             :         }
    1356             : 
    1357           1 :         lock_timeout = (1 + (random() % 20));
    1358           1 :         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
    1359           1 :         t1 = time(NULL);
    1360           1 :         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
    1361           1 :         if (NT_STATUS_IS_OK(status)) {
    1362           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1363           0 :                 return false;
    1364             :         } else {
    1365           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1366           1 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1367           0 :                         return false;
    1368             :                 }
    1369             :         }
    1370           1 :         t2 = time(NULL);
    1371             : 
    1372           1 :         if (ABS(t2 - t1) < lock_timeout-1) {
    1373           0 :                 printf("error: This server appears not to support timed lock requests\n");
    1374             :         }
    1375             : 
    1376           1 :         printf("server slept for %u seconds for a %u second timeout\n",
    1377             :                (unsigned int)(t2-t1), lock_timeout);
    1378             : 
    1379           1 :         status = cli_close(cli1, fnum2);
    1380           1 :         if (!NT_STATUS_IS_OK(status)) {
    1381           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1382           0 :                 return False;
    1383             :         }
    1384             : 
    1385           1 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1386           1 :         if (NT_STATUS_IS_OK(status)) {
    1387           0 :                 printf("lock4 succeeded! This is a locking bug\n");
    1388           0 :                 return false;
    1389             :         } else {
    1390           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1391           1 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1392           0 :                         return false;
    1393             :                 }
    1394             :         }
    1395             : 
    1396           1 :         status = cli_close(cli1, fnum1);
    1397           1 :         if (!NT_STATUS_IS_OK(status)) {
    1398           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1399           0 :                 return False;
    1400             :         }
    1401             : 
    1402           1 :         status = cli_close(cli2, fnum3);
    1403           1 :         if (!NT_STATUS_IS_OK(status)) {
    1404           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1405           0 :                 return False;
    1406             :         }
    1407             : 
    1408           1 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1409           1 :         if (!NT_STATUS_IS_OK(status)) {
    1410           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1411           0 :                 return False;
    1412             :         }
    1413             : 
    1414             : 
    1415           1 :         if (!torture_close_connection(cli1)) {
    1416           0 :                 return False;
    1417             :         }
    1418             : 
    1419           1 :         if (!torture_close_connection(cli2)) {
    1420           0 :                 return False;
    1421             :         }
    1422             : 
    1423           1 :         printf("Passed locktest1\n");
    1424           1 :         return True;
    1425             : }
    1426             : 
    1427             : /*
    1428             :   this checks to see if a secondary tconx can use open files from an
    1429             :   earlier tconx
    1430             :  */
    1431           1 : static bool run_tcon_test(int dummy)
    1432             : {
    1433             :         static struct cli_state *cli;
    1434           1 :         const char *fname = "\\tcontest.tmp";
    1435             :         uint16_t fnum1;
    1436             :         uint32_t cnum1, cnum2, cnum3;
    1437           1 :         struct smbXcli_tcon *orig_tcon = NULL;
    1438             :         uint16_t vuid1, vuid2;
    1439             :         char buf[4];
    1440           1 :         bool ret = True;
    1441             :         NTSTATUS status;
    1442             : 
    1443           1 :         memset(buf, '\0', sizeof(buf));
    1444             : 
    1445           1 :         if (!torture_open_connection(&cli, 0)) {
    1446           0 :                 return False;
    1447             :         }
    1448           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1449             : 
    1450           1 :         printf("starting tcontest\n");
    1451             : 
    1452           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1453             : 
    1454           1 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1455           1 :         if (!NT_STATUS_IS_OK(status)) {
    1456           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1457           0 :                 return False;
    1458             :         }
    1459             : 
    1460           1 :         cnum1 = cli_state_get_tid(cli);
    1461           1 :         vuid1 = cli_state_get_uid(cli);
    1462             : 
    1463           1 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1464           1 :         if (!NT_STATUS_IS_OK(status)) {
    1465           0 :                 printf("initial write failed (%s)", nt_errstr(status));
    1466           0 :                 return False;
    1467             :         }
    1468             : 
    1469           1 :         orig_tcon = cli_state_save_tcon(cli);
    1470           1 :         if (orig_tcon == NULL) {
    1471           0 :                 return false;
    1472             :         }
    1473             : 
    1474           1 :         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
    1475           1 :         if (!NT_STATUS_IS_OK(status)) {
    1476           0 :                 printf("%s refused 2nd tree connect (%s)\n", host,
    1477             :                        nt_errstr(status));
    1478           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1479           0 :                 cli_shutdown(cli);
    1480           0 :                 return False;
    1481             :         }
    1482             : 
    1483           1 :         cnum2 = cli_state_get_tid(cli);
    1484           1 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
    1485           1 :         vuid2 = cli_state_get_uid(cli) + 1;
    1486             : 
    1487             :         /* try a write with the wrong tid */
    1488           1 :         cli_state_set_tid(cli, cnum2);
    1489             : 
    1490           1 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1491           1 :         if (NT_STATUS_IS_OK(status)) {
    1492           0 :                 printf("* server allows write with wrong TID\n");
    1493           0 :                 ret = False;
    1494             :         } else {
    1495           1 :                 printf("server fails write with wrong TID : %s\n",
    1496             :                        nt_errstr(status));
    1497             :         }
    1498             : 
    1499             : 
    1500             :         /* try a write with an invalid tid */
    1501           1 :         cli_state_set_tid(cli, cnum3);
    1502             : 
    1503           1 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1504           1 :         if (NT_STATUS_IS_OK(status)) {
    1505           0 :                 printf("* server allows write with invalid TID\n");
    1506           0 :                 ret = False;
    1507             :         } else {
    1508           1 :                 printf("server fails write with invalid TID : %s\n",
    1509             :                        nt_errstr(status));
    1510             :         }
    1511             : 
    1512             :         /* try a write with an invalid vuid */
    1513           1 :         cli_state_set_uid(cli, vuid2);
    1514           1 :         cli_state_set_tid(cli, cnum1);
    1515             : 
    1516           1 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1517           1 :         if (NT_STATUS_IS_OK(status)) {
    1518           0 :                 printf("* server allows write with invalid VUID\n");
    1519           0 :                 ret = False;
    1520             :         } else {
    1521           1 :                 printf("server fails write with invalid VUID : %s\n",
    1522             :                        nt_errstr(status));
    1523             :         }
    1524             : 
    1525           1 :         cli_state_set_tid(cli, cnum1);
    1526           1 :         cli_state_set_uid(cli, vuid1);
    1527             : 
    1528           1 :         status = cli_close(cli, fnum1);
    1529           1 :         if (!NT_STATUS_IS_OK(status)) {
    1530           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1531           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1532           0 :                 cli_shutdown(cli);
    1533           0 :                 return False;
    1534             :         }
    1535             : 
    1536           1 :         cli_state_set_tid(cli, cnum2);
    1537             : 
    1538           1 :         status = cli_tdis(cli);
    1539           1 :         if (!NT_STATUS_IS_OK(status)) {
    1540           0 :                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
    1541           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1542           0 :                 cli_shutdown(cli);
    1543           0 :                 return False;
    1544             :         }
    1545             : 
    1546           1 :         cli_state_restore_tcon(cli, orig_tcon);
    1547             : 
    1548           1 :         cli_state_set_tid(cli, cnum1);
    1549             : 
    1550           1 :         if (!torture_close_connection(cli)) {
    1551           0 :                 return False;
    1552             :         }
    1553             : 
    1554           1 :         return ret;
    1555             : }
    1556             : 
    1557             : 
    1558             : /*
    1559             :  checks for old style tcon support
    1560             :  */
    1561           1 : static bool run_tcon2_test(int dummy)
    1562             : {
    1563             :         static struct cli_state *cli;
    1564             :         uint16_t cnum, max_xmit;
    1565             :         char *service;
    1566             :         NTSTATUS status;
    1567             : 
    1568           1 :         if (!torture_open_connection(&cli, 0)) {
    1569           0 :                 return False;
    1570             :         }
    1571           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1572             : 
    1573           1 :         printf("starting tcon2 test\n");
    1574             : 
    1575           1 :         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
    1576           0 :                 return false;
    1577             :         }
    1578             : 
    1579           1 :         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
    1580             : 
    1581           1 :         SAFE_FREE(service);
    1582             : 
    1583           1 :         if (!NT_STATUS_IS_OK(status)) {
    1584           1 :                 printf("tcon2 failed : %s\n", nt_errstr(status));
    1585             :         } else {
    1586           0 :                 printf("tcon OK : max_xmit=%d cnum=%d\n",
    1587             :                        (int)max_xmit, (int)cnum);
    1588             :         }
    1589             : 
    1590           1 :         if (!torture_close_connection(cli)) {
    1591           0 :                 return False;
    1592             :         }
    1593             : 
    1594           1 :         printf("Passed tcon2 test\n");
    1595           1 :         return True;
    1596             : }
    1597             : 
    1598          10 : static bool tcon_devtest(struct cli_state *cli,
    1599             :                          const char *myshare, const char *devtype,
    1600             :                          const char *return_devtype,
    1601             :                          NTSTATUS expected_error)
    1602             : {
    1603             :         NTSTATUS status;
    1604             :         bool ret;
    1605             : 
    1606          10 :         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
    1607             : 
    1608          10 :         if (NT_STATUS_IS_OK(expected_error)) {
    1609           4 :                 if (NT_STATUS_IS_OK(status)) {
    1610           8 :                         if (return_devtype != NULL &&
    1611           4 :                             strequal(cli->dev, return_devtype)) {
    1612           4 :                                 ret = True;
    1613             :                         } else { 
    1614           0 :                                 printf("tconX to share %s with type %s "
    1615             :                                        "succeeded but returned the wrong "
    1616             :                                        "device type (got [%s] but should have got [%s])\n",
    1617             :                                        myshare, devtype, cli->dev, return_devtype);
    1618           0 :                                 ret = False;
    1619             :                         }
    1620             :                 } else {
    1621           0 :                         printf("tconX to share %s with type %s "
    1622             :                                "should have succeeded but failed\n",
    1623             :                                myshare, devtype);
    1624           0 :                         ret = False;
    1625             :                 }
    1626           4 :                 cli_tdis(cli);
    1627             :         } else {
    1628           6 :                 if (NT_STATUS_IS_OK(status)) {
    1629           0 :                         printf("tconx to share %s with type %s "
    1630             :                                "should have failed but succeeded\n",
    1631             :                                myshare, devtype);
    1632           0 :                         ret = False;
    1633             :                 } else {
    1634           6 :                         if (NT_STATUS_EQUAL(status, expected_error)) {
    1635           6 :                                 ret = True;
    1636             :                         } else {
    1637           0 :                                 printf("Returned unexpected error\n");
    1638           0 :                                 ret = False;
    1639             :                         }
    1640             :                 }
    1641             :         }
    1642          10 :         return ret;
    1643             : }
    1644             : 
    1645             : /*
    1646             :  checks for correct tconX support
    1647             :  */
    1648           1 : static bool run_tcon_devtype_test(int dummy)
    1649             : {
    1650             :         static struct cli_state *cli1 = NULL;
    1651           1 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
    1652             :         NTSTATUS status;
    1653           1 :         bool ret = True;
    1654             : 
    1655           1 :         status = cli_full_connection_creds(&cli1,
    1656             :                                            myname,
    1657             :                                            host,
    1658             :                                            NULL, /* dest_ss */
    1659             :                                            port_to_use,
    1660             :                                            NULL, /* service */
    1661             :                                            NULL, /* service_type */
    1662             :                                            torture_creds,
    1663             :                                            flags);
    1664             : 
    1665           1 :         if (!NT_STATUS_IS_OK(status)) {
    1666           0 :                 printf("could not open connection\n");
    1667           0 :                 return False;
    1668             :         }
    1669             : 
    1670           1 :         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1671           0 :                 ret = False;
    1672             : 
    1673           1 :         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
    1674           0 :                 ret = False;
    1675             : 
    1676           1 :         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1677           0 :                 ret = False;
    1678             : 
    1679           1 :         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
    1680           0 :                 ret = False;
    1681             : 
    1682           1 :         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1683           0 :                 ret = False;
    1684             : 
    1685           1 :         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
    1686           0 :                 ret = False;
    1687             : 
    1688           1 :         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
    1689           0 :                 ret = False;
    1690             : 
    1691           1 :         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1692           0 :                 ret = False;
    1693             : 
    1694           1 :         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1695           0 :                 ret = False;
    1696             : 
    1697           1 :         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1698           0 :                 ret = False;
    1699             : 
    1700           1 :         cli_shutdown(cli1);
    1701             : 
    1702           1 :         if (ret)
    1703           1 :                 printf("Passed tcondevtest\n");
    1704             : 
    1705           1 :         return ret;
    1706             : }
    1707             : 
    1708             : 
    1709             : /*
    1710             :   This test checks that 
    1711             : 
    1712             :   1) the server supports multiple locking contexts on the one SMB
    1713             :   connection, distinguished by PID.  
    1714             : 
    1715             :   2) the server correctly fails overlapping locks made by the same PID (this
    1716             :      goes against POSIX behaviour, which is why it is tricky to implement)
    1717             : 
    1718             :   3) the server denies unlock requests by an incorrect client PID
    1719             : */
    1720           1 : static bool run_locktest2(int dummy)
    1721             : {
    1722             :         static struct cli_state *cli;
    1723           1 :         const char *fname = "\\lockt2.lck";
    1724             :         uint16_t fnum1, fnum2, fnum3;
    1725           1 :         bool correct = True;
    1726             :         NTSTATUS status;
    1727             : 
    1728           1 :         if (!torture_open_connection(&cli, 0)) {
    1729           0 :                 return False;
    1730             :         }
    1731             : 
    1732           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1733             : 
    1734           1 :         printf("starting locktest2\n");
    1735             : 
    1736           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1737             : 
    1738           1 :         cli_setpid(cli, 1);
    1739             : 
    1740           1 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1741           1 :         if (!NT_STATUS_IS_OK(status)) {
    1742           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1743           0 :                 return False;
    1744             :         }
    1745             : 
    1746           1 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
    1747           1 :         if (!NT_STATUS_IS_OK(status)) {
    1748           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1749           0 :                 return False;
    1750             :         }
    1751             : 
    1752           1 :         cli_setpid(cli, 2);
    1753             : 
    1754           1 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
    1755           1 :         if (!NT_STATUS_IS_OK(status)) {
    1756           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1757           0 :                 return False;
    1758             :         }
    1759             : 
    1760           1 :         cli_setpid(cli, 1);
    1761             : 
    1762           1 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1763           1 :         if (!NT_STATUS_IS_OK(status)) {
    1764           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1765           0 :                 return false;
    1766             :         }
    1767             : 
    1768           1 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1769           1 :         if (NT_STATUS_IS_OK(status)) {
    1770           0 :                 printf("WRITE lock1 succeeded! This is a locking bug\n");
    1771           0 :                 correct = false;
    1772             :         } else {
    1773           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1774           1 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1775           0 :                         return false;
    1776             :                 }
    1777             :         }
    1778             : 
    1779           1 :         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
    1780           1 :         if (NT_STATUS_IS_OK(status)) {
    1781           0 :                 printf("WRITE lock2 succeeded! This is a locking bug\n");
    1782           0 :                 correct = false;
    1783             :         } else {
    1784           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1785           1 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1786           0 :                         return false;
    1787             :                 }
    1788             :         }
    1789             : 
    1790           1 :         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
    1791           1 :         if (NT_STATUS_IS_OK(status)) {
    1792           0 :                 printf("READ lock2 succeeded! This is a locking bug\n");
    1793           0 :                 correct = false;
    1794             :         } else {
    1795           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1796           1 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
    1797           0 :                         return false;
    1798             :                 }
    1799             :         }
    1800             : 
    1801           1 :         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
    1802           1 :         if (!NT_STATUS_IS_OK(status)) {
    1803           0 :                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
    1804             :         }
    1805           1 :         cli_setpid(cli, 2);
    1806           1 :         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
    1807           0 :                 printf("unlock at 100 succeeded! This is a locking bug\n");
    1808           0 :                 correct = False;
    1809             :         }
    1810             : 
    1811           1 :         status = cli_unlock(cli, fnum1, 0, 4);
    1812           1 :         if (NT_STATUS_IS_OK(status)) {
    1813           0 :                 printf("unlock1 succeeded! This is a locking bug\n");
    1814           0 :                 correct = false;
    1815             :         } else {
    1816           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1817           1 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1818           0 :                         return false;
    1819             :                 }
    1820             :         }
    1821             : 
    1822           1 :         status = cli_unlock(cli, fnum1, 0, 8);
    1823           1 :         if (NT_STATUS_IS_OK(status)) {
    1824           0 :                 printf("unlock2 succeeded! This is a locking bug\n");
    1825           0 :                 correct = false;
    1826             :         } else {
    1827           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1828           1 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1829           0 :                         return false;
    1830             :                 }
    1831             :         }
    1832             : 
    1833           1 :         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
    1834           1 :         if (NT_STATUS_IS_OK(status)) {
    1835           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1836           0 :                 correct = false;
    1837             :         } else {
    1838           1 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1839           1 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1840           0 :                         return false;
    1841             :                 }
    1842             :         }
    1843             : 
    1844           1 :         cli_setpid(cli, 1);
    1845             : 
    1846           1 :         status = cli_close(cli, fnum1);
    1847           1 :         if (!NT_STATUS_IS_OK(status)) {
    1848           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1849           0 :                 return False;
    1850             :         }
    1851             : 
    1852           1 :         status = cli_close(cli, fnum2);
    1853           1 :         if (!NT_STATUS_IS_OK(status)) {
    1854           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1855           0 :                 return False;
    1856             :         }
    1857             : 
    1858           1 :         status = cli_close(cli, fnum3);
    1859           1 :         if (!NT_STATUS_IS_OK(status)) {
    1860           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1861           0 :                 return False;
    1862             :         }
    1863             : 
    1864           1 :         if (!torture_close_connection(cli)) {
    1865           0 :                 correct = False;
    1866             :         }
    1867             : 
    1868           1 :         printf("locktest2 finished\n");
    1869             : 
    1870           1 :         return correct;
    1871             : }
    1872             : 
    1873             : 
    1874             : /*
    1875             :   This test checks that 
    1876             : 
    1877             :   1) the server supports the full offset range in lock requests
    1878             : */
    1879           1 : static bool run_locktest3(int dummy)
    1880             : {
    1881             :         static struct cli_state *cli1, *cli2;
    1882           1 :         const char *fname = "\\lockt3.lck";
    1883             :         uint16_t fnum1, fnum2;
    1884             :         int i;
    1885             :         uint32_t offset;
    1886           1 :         bool correct = True;
    1887             :         NTSTATUS status;
    1888             : 
    1889             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
    1890             : 
    1891           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1892           0 :                 return False;
    1893             :         }
    1894           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1895           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1896             : 
    1897           1 :         printf("starting locktest3\n");
    1898             : 
    1899           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1900             : 
    1901           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1902             :                          &fnum1);
    1903           1 :         if (!NT_STATUS_IS_OK(status)) {
    1904           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1905           0 :                 return False;
    1906             :         }
    1907             : 
    1908           1 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1909           1 :         if (!NT_STATUS_IS_OK(status)) {
    1910           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1911           0 :                 return False;
    1912             :         }
    1913             : 
    1914         101 :         for (offset=i=0;i<torture_numops;i++) {
    1915         100 :                 NEXT_OFFSET;
    1916             : 
    1917         100 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1918         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1919           0 :                         printf("lock1 %d failed (%s)\n", 
    1920             :                                i,
    1921             :                                nt_errstr(status));
    1922           0 :                         return False;
    1923             :                 }
    1924             : 
    1925         100 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1926         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1927           0 :                         printf("lock2 %d failed (%s)\n", 
    1928             :                                i,
    1929             :                                nt_errstr(status));
    1930           0 :                         return False;
    1931             :                 }
    1932             :         }
    1933             : 
    1934         101 :         for (offset=i=0;i<torture_numops;i++) {
    1935         100 :                 NEXT_OFFSET;
    1936             : 
    1937         100 :                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
    1938         100 :                 if (NT_STATUS_IS_OK(status)) {
    1939           0 :                         printf("error: lock1 %d succeeded!\n", i);
    1940           0 :                         return False;
    1941             :                 }
    1942             : 
    1943         100 :                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
    1944         100 :                 if (NT_STATUS_IS_OK(status)) {
    1945           0 :                         printf("error: lock2 %d succeeded!\n", i);
    1946           0 :                         return False;
    1947             :                 }
    1948             : 
    1949         100 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1950         100 :                 if (NT_STATUS_IS_OK(status)) {
    1951           0 :                         printf("error: lock3 %d succeeded!\n", i);
    1952           0 :                         return False;
    1953             :                 }
    1954             : 
    1955         100 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1956         100 :                 if (NT_STATUS_IS_OK(status)) {
    1957           0 :                         printf("error: lock4 %d succeeded!\n", i);
    1958           0 :                         return False;
    1959             :                 }
    1960             :         }
    1961             : 
    1962         101 :         for (offset=i=0;i<torture_numops;i++) {
    1963         100 :                 NEXT_OFFSET;
    1964             : 
    1965         100 :                 status = cli_unlock(cli1, fnum1, offset-1, 1);
    1966         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1967           0 :                         printf("unlock1 %d failed (%s)\n", 
    1968             :                                i,
    1969             :                                nt_errstr(status));
    1970           0 :                         return False;
    1971             :                 }
    1972             : 
    1973         100 :                 status = cli_unlock(cli2, fnum2, offset-2, 1);
    1974         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1975           0 :                         printf("unlock2 %d failed (%s)\n", 
    1976             :                                i,
    1977             :                                nt_errstr(status));
    1978           0 :                         return False;
    1979             :                 }
    1980             :         }
    1981             : 
    1982           1 :         status = cli_close(cli1, fnum1);
    1983           1 :         if (!NT_STATUS_IS_OK(status)) {
    1984           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1985           0 :                 return False;
    1986             :         }
    1987             : 
    1988           1 :         status = cli_close(cli2, fnum2);
    1989           1 :         if (!NT_STATUS_IS_OK(status)) {
    1990           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1991           0 :                 return False;
    1992             :         }
    1993             : 
    1994           1 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1995           1 :         if (!NT_STATUS_IS_OK(status)) {
    1996           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1997           0 :                 return False;
    1998             :         }
    1999             : 
    2000           1 :         if (!torture_close_connection(cli1)) {
    2001           0 :                 correct = False;
    2002             :         }
    2003             : 
    2004           1 :         if (!torture_close_connection(cli2)) {
    2005           0 :                 correct = False;
    2006             :         }
    2007             : 
    2008           1 :         printf("finished locktest3\n");
    2009             : 
    2010           1 :         return correct;
    2011             : }
    2012             : 
    2013           8 : static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
    2014             :                            char *buf, off_t offset, size_t size,
    2015             :                            size_t *nread, size_t expect)
    2016             : {
    2017             :         NTSTATUS status;
    2018             :         size_t l_nread;
    2019             : 
    2020           8 :         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
    2021             : 
    2022           8 :         if(!NT_STATUS_IS_OK(status)) {
    2023           4 :                 return false;
    2024           4 :         } else if (l_nread != expect) {
    2025           0 :                 return false;
    2026             :         }
    2027             : 
    2028           4 :         if (nread) {
    2029           0 :                 *nread = l_nread;
    2030             :         }
    2031             : 
    2032           4 :         return true;
    2033             : }
    2034             : 
    2035             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
    2036             :         printf("** "); correct = False; \
    2037             :         }
    2038             : 
    2039             : /*
    2040             :   looks at overlapping locks
    2041             : */
    2042           1 : static bool run_locktest4(int dummy)
    2043             : {
    2044             :         static struct cli_state *cli1, *cli2;
    2045           1 :         const char *fname = "\\lockt4.lck";
    2046             :         uint16_t fnum1, fnum2, f;
    2047             :         bool ret;
    2048             :         char buf[1000];
    2049           1 :         bool correct = True;
    2050             :         NTSTATUS status;
    2051             : 
    2052           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2053           0 :                 return False;
    2054             :         }
    2055             : 
    2056           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2057           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2058             : 
    2059           1 :         printf("starting locktest4\n");
    2060             : 
    2061           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2062             : 
    2063           1 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2064           1 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2065             : 
    2066           1 :         memset(buf, 0, sizeof(buf));
    2067             : 
    2068           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2069             :                               NULL);
    2070           1 :         if (!NT_STATUS_IS_OK(status)) {
    2071           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2072           0 :                 correct = False;
    2073           0 :                 goto fail;
    2074             :         }
    2075             : 
    2076           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2077           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
    2078           1 :         EXPECTED(ret, False);
    2079           1 :         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
    2080             : 
    2081           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
    2082           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
    2083           1 :         EXPECTED(ret, True);
    2084           1 :         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
    2085             : 
    2086           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
    2087           1 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
    2088           1 :         EXPECTED(ret, False);
    2089           1 :         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
    2090             : 
    2091           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
    2092           1 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
    2093           1 :         EXPECTED(ret, True);
    2094           1 :         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
    2095             : 
    2096           2 :         ret = (cli_setpid(cli1, 1),
    2097           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
    2098           1 :               (cli_setpid(cli1, 2),
    2099           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
    2100           1 :         EXPECTED(ret, False);
    2101           1 :         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
    2102             : 
    2103           2 :         ret = (cli_setpid(cli1, 1),
    2104           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
    2105           1 :               (cli_setpid(cli1, 2),
    2106           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
    2107           1 :         EXPECTED(ret, True);
    2108           1 :         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
    2109             : 
    2110           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
    2111           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
    2112           1 :         EXPECTED(ret, True);
    2113           1 :         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
    2114             : 
    2115           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
    2116           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
    2117           1 :         EXPECTED(ret, False);
    2118           1 :         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
    2119             : 
    2120           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
    2121           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
    2122           1 :         EXPECTED(ret, False);
    2123           1 :         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
    2124             : 
    2125           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
    2126           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
    2127           1 :         EXPECTED(ret, True);
    2128           1 :         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2129             : 
    2130           2 :         ret = (cli_setpid(cli1, 1),
    2131           2 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
    2132           1 :              (cli_setpid(cli1, 2),
    2133           1 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
    2134           1 :         EXPECTED(ret, False);
    2135           1 :         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2136             : 
    2137           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
    2138           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
    2139           1 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
    2140           1 :         EXPECTED(ret, False);
    2141           1 :         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
    2142             : 
    2143             : 
    2144           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
    2145           1 :               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
    2146           1 :         EXPECTED(ret, False);
    2147           1 :         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
    2148             : 
    2149           1 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2150           1 :         ret = NT_STATUS_IS_OK(status);
    2151           1 :         if (ret) {
    2152           1 :                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
    2153             :                                       NULL);
    2154           1 :                 ret = NT_STATUS_IS_OK(status);
    2155             :         }
    2156           1 :         EXPECTED(ret, False);
    2157           1 :         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
    2158             : 
    2159             : 
    2160           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2161           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2162           3 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
    2163           1 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
    2164           1 :         EXPECTED(ret, True);
    2165           1 :         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
    2166             : 
    2167             : 
    2168           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
    2169           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
    2170           2 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
    2171           2 :               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
    2172           1 :               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2173           2 :                                              150, 4, NULL))) &&
    2174           1 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
    2175           1 :         EXPECTED(ret, True);
    2176           1 :         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
    2177             : 
    2178           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
    2179           2 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
    2180           1 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2181           2 :                                            160, 4, NULL)) &&
    2182           1 :               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
    2183           1 :         EXPECTED(ret, True);
    2184           1 :         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
    2185             : 
    2186           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
    2187           2 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
    2188           1 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2189           2 :                                            170, 4, NULL)) &&
    2190           1 :               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
    2191           1 :         EXPECTED(ret, True);
    2192           1 :         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
    2193             : 
    2194           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
    2195           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
    2196           2 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
    2197           1 :               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2198           2 :                                             190, 4, NULL)) &&
    2199           1 :               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
    2200           1 :         EXPECTED(ret, True);
    2201           1 :         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
    2202             : 
    2203           1 :         cli_close(cli1, fnum1);
    2204           1 :         cli_close(cli2, fnum2);
    2205           1 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2206           1 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
    2207           3 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2208           2 :               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
    2209           2 :               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
    2210           3 :               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
    2211           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
    2212           1 :         cli_close(cli1, f);
    2213           1 :         cli_close(cli1, fnum1);
    2214           1 :         EXPECTED(ret, True);
    2215           1 :         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
    2216             : 
    2217           1 :  fail:
    2218           1 :         cli_close(cli1, fnum1);
    2219           1 :         cli_close(cli2, fnum2);
    2220           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2221           1 :         torture_close_connection(cli1);
    2222           1 :         torture_close_connection(cli2);
    2223             : 
    2224           1 :         printf("finished locktest4\n");
    2225           1 :         return correct;
    2226             : }
    2227             : 
    2228             : /*
    2229             :   looks at lock upgrade/downgrade.
    2230             : */
    2231           1 : static bool run_locktest5(int dummy)
    2232             : {
    2233             :         static struct cli_state *cli1, *cli2;
    2234           1 :         const char *fname = "\\lockt5.lck";
    2235             :         uint16_t fnum1, fnum2, fnum3;
    2236             :         bool ret;
    2237             :         char buf[1000];
    2238           1 :         bool correct = True;
    2239             :         NTSTATUS status;
    2240             : 
    2241           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2242           0 :                 return False;
    2243             :         }
    2244             : 
    2245           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2246           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2247             : 
    2248           1 :         printf("starting locktest5\n");
    2249             : 
    2250           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2251             : 
    2252           1 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2253           1 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2254           1 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
    2255             : 
    2256           1 :         memset(buf, 0, sizeof(buf));
    2257             : 
    2258           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2259             :                               NULL);
    2260           1 :         if (!NT_STATUS_IS_OK(status)) {
    2261           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2262           0 :                 correct = False;
    2263           0 :                 goto fail;
    2264             :         }
    2265             : 
    2266             :         /* Check for NT bug... */
    2267           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2268           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
    2269           1 :         cli_close(cli1, fnum1);
    2270           1 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2271           1 :         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
    2272           1 :         ret = NT_STATUS_IS_OK(status);
    2273           1 :         EXPECTED(ret, True);
    2274           1 :         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
    2275           1 :         cli_close(cli1, fnum1);
    2276           1 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2277           1 :         cli_unlock(cli1, fnum3, 0, 1);
    2278             : 
    2279           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2280           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
    2281           1 :         EXPECTED(ret, True);
    2282           1 :         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
    2283             : 
    2284           1 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
    2285           1 :         ret = NT_STATUS_IS_OK(status);
    2286           1 :         EXPECTED(ret, False);
    2287             : 
    2288           1 :         printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
    2289             : 
    2290             :         /* Unlock the process 2 lock. */
    2291           1 :         cli_unlock(cli2, fnum2, 0, 4);
    2292             : 
    2293           1 :         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
    2294           1 :         ret = NT_STATUS_IS_OK(status);
    2295           1 :         EXPECTED(ret, False);
    2296             : 
    2297           1 :         printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
    2298             : 
    2299             :         /* Unlock the process 1 fnum3 lock. */
    2300           1 :         cli_unlock(cli1, fnum3, 0, 4);
    2301             : 
    2302             :         /* Stack 2 more locks here. */
    2303           2 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
    2304           1 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
    2305             : 
    2306           1 :         EXPECTED(ret, True);
    2307           1 :         printf("the same process %s stack read locks\n", ret?"can":"cannot");
    2308             : 
    2309             :         /* Unlock the first process lock, then check this was the WRITE lock that was
    2310             :                 removed. */
    2311             : 
    2312           2 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2313           1 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
    2314             : 
    2315           1 :         EXPECTED(ret, True);
    2316           1 :         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
    2317             : 
    2318             :         /* Unlock the process 2 lock. */
    2319           1 :         cli_unlock(cli2, fnum2, 0, 4);
    2320             : 
    2321             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
    2322             : 
    2323           3 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
    2324           2 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2325           1 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2326             : 
    2327           1 :         EXPECTED(ret, True);
    2328           1 :         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
    2329             : 
    2330             :         /* Ensure the next unlock fails. */
    2331           1 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2332           1 :         EXPECTED(ret, False);
    2333           1 :         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
    2334             : 
    2335             :         /* Ensure connection 2 can get a write lock. */
    2336           1 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
    2337           1 :         ret = NT_STATUS_IS_OK(status);
    2338           1 :         EXPECTED(ret, True);
    2339             : 
    2340           1 :         printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
    2341             : 
    2342             : 
    2343           1 :  fail:
    2344           1 :         cli_close(cli1, fnum1);
    2345           1 :         cli_close(cli2, fnum2);
    2346           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2347           1 :         if (!torture_close_connection(cli1)) {
    2348           0 :                 correct = False;
    2349             :         }
    2350           1 :         if (!torture_close_connection(cli2)) {
    2351           0 :                 correct = False;
    2352             :         }
    2353             : 
    2354           1 :         printf("finished locktest5\n");
    2355             : 
    2356           1 :         return correct;
    2357             : }
    2358             : 
    2359             : /*
    2360             :   tries the unusual lockingX locktype bits
    2361             : */
    2362           1 : static bool run_locktest6(int dummy)
    2363             : {
    2364             :         static struct cli_state *cli;
    2365           1 :         const char *fname[1] = { "\\lock6.txt" };
    2366             :         int i;
    2367             :         uint16_t fnum;
    2368             :         NTSTATUS status;
    2369             : 
    2370           1 :         if (!torture_open_connection(&cli, 0)) {
    2371           0 :                 return False;
    2372             :         }
    2373             : 
    2374           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    2375             : 
    2376           1 :         printf("starting locktest6\n");
    2377             : 
    2378           2 :         for (i=0;i<1;i++) {
    2379           1 :                 printf("Testing %s\n", fname[i]);
    2380             : 
    2381           1 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2382             : 
    2383           1 :                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    2384           1 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
    2385           1 :                 cli_close(cli, fnum);
    2386           1 :                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
    2387             : 
    2388           1 :                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
    2389           1 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
    2390           1 :                 cli_close(cli, fnum);
    2391           1 :                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
    2392             : 
    2393           1 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2394             :         }
    2395             : 
    2396           1 :         torture_close_connection(cli);
    2397             : 
    2398           1 :         printf("finished locktest6\n");
    2399           1 :         return True;
    2400             : }
    2401             : 
    2402           1 : static bool run_locktest7(int dummy)
    2403             : {
    2404             :         struct cli_state *cli1;
    2405           1 :         const char *fname = "\\lockt7.lck";
    2406             :         uint16_t fnum1;
    2407             :         char buf[200];
    2408           1 :         bool correct = False;
    2409             :         size_t nread;
    2410             :         NTSTATUS status;
    2411             : 
    2412           1 :         if (!torture_open_connection(&cli1, 0)) {
    2413           0 :                 return False;
    2414             :         }
    2415             : 
    2416           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2417             : 
    2418           1 :         printf("starting locktest7\n");
    2419             : 
    2420           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2421             : 
    2422           1 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2423             : 
    2424           1 :         memset(buf, 0, sizeof(buf));
    2425             : 
    2426           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2427             :                               NULL);
    2428           1 :         if (!NT_STATUS_IS_OK(status)) {
    2429           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2430           0 :                 goto fail;
    2431             :         }
    2432             : 
    2433           1 :         cli_setpid(cli1, 1);
    2434             : 
    2435           1 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2436           1 :         if (!NT_STATUS_IS_OK(status)) {
    2437           0 :                 printf("Unable to apply read lock on range 130:4, "
    2438             :                        "error was %s\n", nt_errstr(status));
    2439           0 :                 goto fail;
    2440             :         } else {
    2441           1 :                 printf("pid1 successfully locked range 130:4 for READ\n");
    2442             :         }
    2443             : 
    2444           1 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2445           1 :         if (!NT_STATUS_IS_OK(status)) {
    2446           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2447             :                       nt_errstr(status));
    2448           0 :                 goto fail;
    2449           1 :         } else if (nread != 4) {
    2450           0 :                 printf("pid1 unable to read the range 130:4, "
    2451             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2452           0 :                 goto fail;
    2453             :         } else {
    2454           1 :                 printf("pid1 successfully read the range 130:4\n");
    2455             :         }
    2456             : 
    2457           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2458           1 :         if (!NT_STATUS_IS_OK(status)) {
    2459           1 :                 printf("pid1 unable to write to the range 130:4, error was "
    2460             :                        "%s\n", nt_errstr(status));
    2461           1 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2462           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2463           0 :                         goto fail;
    2464             :                 }
    2465             :         } else {
    2466           0 :                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
    2467           0 :                 goto fail;
    2468             :         }
    2469             : 
    2470           1 :         cli_setpid(cli1, 2);
    2471             : 
    2472           1 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2473           1 :         if (!NT_STATUS_IS_OK(status)) {
    2474           0 :                 printf("pid2 unable to read the range 130:4, error was %s\n",
    2475             :                       nt_errstr(status));
    2476           0 :                 goto fail;
    2477           1 :         } else if (nread != 4) {
    2478           0 :                 printf("pid2 unable to read the range 130:4, "
    2479             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2480           0 :                 goto fail;
    2481             :         } else {
    2482           1 :                 printf("pid2 successfully read the range 130:4\n");
    2483             :         }
    2484             : 
    2485           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2486           1 :         if (!NT_STATUS_IS_OK(status)) {
    2487           1 :                 printf("pid2 unable to write to the range 130:4, error was "
    2488             :                        "%s\n", nt_errstr(status));
    2489           1 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2490           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2491           0 :                         goto fail;
    2492             :                 }
    2493             :         } else {
    2494           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2495           0 :                 goto fail;
    2496             :         }
    2497             : 
    2498           1 :         cli_setpid(cli1, 1);
    2499           1 :         cli_unlock(cli1, fnum1, 130, 4);
    2500             : 
    2501           1 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
    2502           1 :         if (!NT_STATUS_IS_OK(status)) {
    2503           0 :                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
    2504           0 :                 goto fail;
    2505             :         } else {
    2506           1 :                 printf("pid1 successfully locked range 130:4 for WRITE\n");
    2507             :         }
    2508             : 
    2509           1 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2510           1 :         if (!NT_STATUS_IS_OK(status)) {
    2511           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2512             :                       nt_errstr(status));
    2513           0 :                 goto fail;
    2514           1 :         } else if (nread != 4) {
    2515           0 :                 printf("pid1 unable to read the range 130:4, "
    2516             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2517           0 :                 goto fail;
    2518             :         } else {
    2519           1 :                 printf("pid1 successfully read the range 130:4\n");
    2520             :         }
    2521             : 
    2522           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2523           1 :         if (!NT_STATUS_IS_OK(status)) {
    2524           0 :                 printf("pid1 unable to write to the range 130:4, error was "
    2525             :                        "%s\n", nt_errstr(status));
    2526           0 :                 goto fail;
    2527             :         } else {
    2528           1 :                 printf("pid1 successfully wrote to the range 130:4\n");
    2529             :         }
    2530             : 
    2531           1 :         cli_setpid(cli1, 2);
    2532             : 
    2533           1 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2534           1 :         if (!NT_STATUS_IS_OK(status)) {
    2535           1 :                 printf("pid2 unable to read the range 130:4, error was "
    2536             :                        "%s\n", nt_errstr(status));
    2537           1 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2538           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2539           0 :                         goto fail;
    2540             :                 }
    2541             :         } else {
    2542           0 :                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
    2543             :                        (unsigned long)nread);
    2544           0 :                 goto fail;
    2545             :         }
    2546             : 
    2547           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2548           1 :         if (!NT_STATUS_IS_OK(status)) {
    2549           1 :                 printf("pid2 unable to write to the range 130:4, error was "
    2550             :                        "%s\n", nt_errstr(status));
    2551           1 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2552           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2553           0 :                         goto fail;
    2554             :                 }
    2555             :         } else {
    2556           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2557           0 :                 goto fail;
    2558             :         }
    2559             : 
    2560           1 :         cli_unlock(cli1, fnum1, 130, 0);
    2561           1 :         correct = True;
    2562             : 
    2563           1 : fail:
    2564           1 :         cli_close(cli1, fnum1);
    2565           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2566           1 :         torture_close_connection(cli1);
    2567             : 
    2568           1 :         printf("finished locktest7\n");
    2569           1 :         return correct;
    2570             : }
    2571             : 
    2572             : /*
    2573             :  * This demonstrates a problem with our use of GPFS share modes: A file
    2574             :  * descriptor sitting in the pending close queue holding a GPFS share mode
    2575             :  * blocks opening a file another time. Happens with Word 2007 temp files.
    2576             :  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
    2577             :  * open is denied with NT_STATUS_SHARING_VIOLATION.
    2578             :  */
    2579             : 
    2580           0 : static bool run_locktest8(int dummy)
    2581             : {
    2582             :         struct cli_state *cli1;
    2583           0 :         const char *fname = "\\lockt8.lck";
    2584             :         uint16_t fnum1, fnum2;
    2585             :         char buf[200];
    2586           0 :         bool correct = False;
    2587             :         NTSTATUS status;
    2588             : 
    2589           0 :         if (!torture_open_connection(&cli1, 0)) {
    2590           0 :                 return False;
    2591             :         }
    2592             : 
    2593           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2594             : 
    2595           0 :         printf("starting locktest8\n");
    2596             : 
    2597           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2598             : 
    2599           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
    2600             :                           &fnum1);
    2601           0 :         if (!NT_STATUS_IS_OK(status)) {
    2602           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2603           0 :                 return false;
    2604             :         }
    2605             : 
    2606           0 :         memset(buf, 0, sizeof(buf));
    2607             : 
    2608           0 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
    2609           0 :         if (!NT_STATUS_IS_OK(status)) {
    2610           0 :                 d_fprintf(stderr, "cli_openx second time returned %s\n",
    2611             :                           nt_errstr(status));
    2612           0 :                 goto fail;
    2613             :         }
    2614             : 
    2615           0 :         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
    2616           0 :         if (!NT_STATUS_IS_OK(status)) {
    2617           0 :                 printf("Unable to apply read lock on range 1:1, error was "
    2618             :                        "%s\n", nt_errstr(status));
    2619           0 :                 goto fail;
    2620             :         }
    2621             : 
    2622           0 :         status = cli_close(cli1, fnum1);
    2623           0 :         if (!NT_STATUS_IS_OK(status)) {
    2624           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2625           0 :                 goto fail;
    2626             :         }
    2627             : 
    2628           0 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2629           0 :         if (!NT_STATUS_IS_OK(status)) {
    2630           0 :                 d_fprintf(stderr, "cli_openx third time returned %s\n",
    2631             :                           nt_errstr(status));
    2632           0 :                 goto fail;
    2633             :         }
    2634             : 
    2635           0 :         correct = true;
    2636             : 
    2637           0 : fail:
    2638           0 :         cli_close(cli1, fnum1);
    2639           0 :         cli_close(cli1, fnum2);
    2640           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2641           0 :         torture_close_connection(cli1);
    2642             : 
    2643           0 :         printf("finished locktest8\n");
    2644           0 :         return correct;
    2645             : }
    2646             : 
    2647             : /*
    2648             :  * This test is designed to be run in conjunction with
    2649             :  * external NFS or POSIX locks taken in the filesystem.
    2650             :  * It checks that the smbd server will block until the
    2651             :  * lock is released and then acquire it. JRA.
    2652             :  */
    2653             : 
    2654             : static bool got_alarm;
    2655             : static struct cli_state *alarm_cli;
    2656             : 
    2657           0 : static void alarm_handler(int dummy)
    2658             : {
    2659           0 :         got_alarm = True;
    2660           0 : }
    2661             : 
    2662           0 : static void alarm_handler_parent(int dummy)
    2663             : {
    2664           0 :         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    2665           0 : }
    2666             : 
    2667           0 : static void do_local_lock(const char *fname, int read_fd, int write_fd)
    2668             : {
    2669             :         int fd;
    2670           0 :         char c = '\0';
    2671             :         struct flock lock;
    2672           0 :         const char *local_pathname = NULL;
    2673             :         int ret;
    2674             : 
    2675           0 :         local_pathname = talloc_asprintf(talloc_tos(),
    2676             :                         "%s/%s", local_path, fname);
    2677           0 :         if (!local_pathname) {
    2678           0 :                 printf("child: alloc fail\n");
    2679           0 :                 exit(1);
    2680             :         }
    2681             : 
    2682           0 :         unlink(local_pathname);
    2683           0 :         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
    2684           0 :         if (fd == -1) {
    2685           0 :                 printf("child: open of %s failed %s.\n",
    2686           0 :                         local_pathname, strerror(errno));
    2687           0 :                 exit(1);
    2688             :         }
    2689             : 
    2690             :         /* Now take a fcntl lock. */
    2691           0 :         lock.l_type = F_WRLCK;
    2692           0 :         lock.l_whence = SEEK_SET;
    2693           0 :         lock.l_start = 0;
    2694           0 :         lock.l_len = 4;
    2695           0 :         lock.l_pid = getpid();
    2696             : 
    2697           0 :         ret = fcntl(fd,F_SETLK,&lock);
    2698           0 :         if (ret == -1) {
    2699           0 :                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
    2700           0 :                         local_pathname, strerror(errno));
    2701           0 :                 exit(1);
    2702             :         } else {
    2703           0 :                 printf("child: got lock 0:4 on file %s.\n",
    2704             :                         local_pathname );
    2705           0 :                 fflush(stdout);
    2706             :         }
    2707             : 
    2708           0 :         CatchSignal(SIGALRM, alarm_handler);
    2709           0 :         alarm(5);
    2710             :         /* Signal the parent. */
    2711           0 :         if (write(write_fd, &c, 1) != 1) {
    2712           0 :                 printf("child: start signal fail %s.\n",
    2713           0 :                         strerror(errno));
    2714           0 :                 exit(1);
    2715             :         }
    2716           0 :         alarm(0);
    2717             : 
    2718           0 :         alarm(10);
    2719             :         /* Wait for the parent to be ready. */
    2720           0 :         if (read(read_fd, &c, 1) != 1) {
    2721           0 :                 printf("child: reply signal fail %s.\n",
    2722           0 :                         strerror(errno));
    2723           0 :                 exit(1);
    2724             :         }
    2725           0 :         alarm(0);
    2726             : 
    2727           0 :         sleep(5);
    2728           0 :         close(fd);
    2729           0 :         printf("child: released lock 0:4 on file %s.\n",
    2730             :                 local_pathname );
    2731           0 :         fflush(stdout);
    2732           0 :         exit(0);
    2733             : }
    2734             : 
    2735           0 : static bool _run_locktest9X(const char *fname, int timeout)
    2736             : {
    2737             :         struct cli_state *cli1;
    2738           0 :         char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname);
    2739             :         uint16_t fnum;
    2740           0 :         bool correct = False;
    2741             :         int pipe_in[2], pipe_out[2];
    2742             :         pid_t child_pid;
    2743           0 :         char c = '\0';
    2744             :         int ret;
    2745             :         struct timeval start;
    2746             :         double seconds;
    2747             :         NTSTATUS status;
    2748             : 
    2749           0 :         printf("starting locktest9X: %s\n", fname);
    2750             : 
    2751           0 :         if (local_path == NULL) {
    2752           0 :                 d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n");
    2753           0 :                 return false;
    2754             :         }
    2755             : 
    2756           0 :         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
    2757           0 :                 return false;
    2758             :         }
    2759             : 
    2760           0 :         child_pid = fork();
    2761           0 :         if (child_pid == -1) {
    2762           0 :                 return false;
    2763             :         }
    2764             : 
    2765           0 :         if (child_pid == 0) {
    2766             :                 /* Child. */
    2767           0 :                 do_local_lock(fname, pipe_out[0], pipe_in[1]);
    2768           0 :                 exit(0);
    2769             :         }
    2770             : 
    2771           0 :         close(pipe_out[0]);
    2772           0 :         close(pipe_in[1]);
    2773           0 :         pipe_out[0] = -1;
    2774           0 :         pipe_in[1] = -1;
    2775             : 
    2776             :         /* Parent. */
    2777           0 :         ret = read(pipe_in[0], &c, 1);
    2778           0 :         if (ret != 1) {
    2779           0 :                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
    2780           0 :                         strerror(errno));
    2781           0 :                 return false;
    2782             :         }
    2783             : 
    2784           0 :         if (!torture_open_connection(&cli1, 0)) {
    2785           0 :                 return false;
    2786             :         }
    2787             : 
    2788           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2789             : 
    2790           0 :         status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE,
    2791             :                           &fnum);
    2792           0 :         if (!NT_STATUS_IS_OK(status)) {
    2793           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2794           0 :                 return false;
    2795             :         }
    2796             : 
    2797             :         /* Ensure the child has the lock. */
    2798           0 :         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
    2799           0 :         if (NT_STATUS_IS_OK(status)) {
    2800           0 :                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
    2801           0 :                 goto fail;
    2802             :         } else {
    2803           0 :                 d_printf("Child has the lock.\n");
    2804             :         }
    2805             : 
    2806             :         /* Tell the child to wait 5 seconds then exit. */
    2807           0 :         ret = write(pipe_out[1], &c, 1);
    2808           0 :         if (ret != 1) {
    2809           0 :                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
    2810           0 :                         strerror(errno));
    2811           0 :                 goto fail;
    2812             :         }
    2813             : 
    2814             :         /* Wait 20 seconds for the lock. */
    2815           0 :         alarm_cli = cli1;
    2816           0 :         CatchSignal(SIGALRM, alarm_handler_parent);
    2817           0 :         alarm(20);
    2818             : 
    2819           0 :         start = timeval_current();
    2820             : 
    2821           0 :         status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK);
    2822           0 :         if (!NT_STATUS_IS_OK(status)) {
    2823           0 :                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
    2824             :                        "%s\n", nt_errstr(status));
    2825           0 :                 goto fail_nofd;
    2826             :         }
    2827           0 :         alarm(0);
    2828             : 
    2829           0 :         seconds = timeval_elapsed(&start);
    2830             : 
    2831           0 :         printf("Parent got the lock after %.2f seconds.\n",
    2832             :                 seconds);
    2833             : 
    2834           0 :         status = cli_close(cli1, fnum);
    2835           0 :         if (!NT_STATUS_IS_OK(status)) {
    2836           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2837           0 :                 goto fail;
    2838             :         }
    2839             : 
    2840           0 :         correct = true;
    2841             : 
    2842           0 : fail:
    2843           0 :         cli_close(cli1, fnum);
    2844           0 :         torture_close_connection(cli1);
    2845             : 
    2846           0 : fail_nofd:
    2847             : 
    2848           0 :         printf("finished locktest9X: %s\n", fname);
    2849           0 :         return correct;
    2850             : }
    2851             : 
    2852           0 : static bool run_locktest9a(int dummy)
    2853             : {
    2854           0 :         return _run_locktest9X("lock9a.dat", -1);
    2855             : }
    2856             : 
    2857           0 : static bool run_locktest9b(int dummy)
    2858             : {
    2859           0 :         return _run_locktest9X("lock9b.dat", 10000);
    2860             : }
    2861             : 
    2862             : struct locktest10_state {
    2863             :         bool ok;
    2864             :         bool done;
    2865             : };
    2866             : 
    2867             : static void locktest10_lockingx_done(struct tevent_req *subreq);
    2868             : static void locktest10_read_andx_done(struct tevent_req *subreq);
    2869             : 
    2870           1 : static bool run_locktest10(int dummy)
    2871             : {
    2872           1 :         struct tevent_context *ev = NULL;
    2873           1 :         struct cli_state *cli1 = NULL;
    2874           1 :         struct cli_state *cli2 = NULL;
    2875           1 :         struct smb1_lock_element lck = { 0 };
    2876           1 :         struct tevent_req *reqs[2] = { NULL };
    2877           1 :         struct tevent_req *smbreqs[2] = { NULL };
    2878           1 :         const char fname[] = "\\lockt10.lck";
    2879             :         uint16_t fnum1, fnum2;
    2880           1 :         bool ret = false;
    2881             :         bool ok;
    2882           1 :         uint8_t data = 1;
    2883           1 :         struct locktest10_state state = { .ok = true };
    2884             :         NTSTATUS status;
    2885             : 
    2886           1 :         printf("starting locktest10\n");
    2887             : 
    2888           1 :         ev = samba_tevent_context_init(NULL);
    2889           1 :         if (ev == NULL) {
    2890           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    2891           0 :                 goto done;
    2892             :         }
    2893             : 
    2894           1 :         ok = torture_open_connection(&cli1, 0);
    2895           1 :         if (!ok) {
    2896           0 :                 goto done;
    2897             :         }
    2898           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2899             : 
    2900           1 :         ok = torture_open_connection(&cli2, 1);
    2901           1 :         if (!ok) {
    2902           0 :                 goto done;
    2903             :         }
    2904           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2905             : 
    2906           1 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    2907           1 :         if (!NT_STATUS_IS_OK(status)) {
    2908           0 :                 d_fprintf(stderr,
    2909             :                           "cli_openx failed: %s\n",
    2910             :                           nt_errstr(status));
    2911           0 :                 goto done;
    2912             :         }
    2913             : 
    2914           1 :         status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
    2915           1 :         if (!NT_STATUS_IS_OK(status)) {
    2916           0 :                 d_fprintf(stderr,
    2917             :                           "cli_writeall failed: %s\n",
    2918             :                           nt_errstr(status));
    2919           0 :                 goto done;
    2920             :         }
    2921             : 
    2922           1 :         status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    2923           1 :         if (!NT_STATUS_IS_OK(status)) {
    2924           0 :                 d_fprintf(stderr,
    2925             :                           "cli_openx failed: %s\n",
    2926             :                           nt_errstr(status));
    2927           0 :                 goto done;
    2928             :         }
    2929             : 
    2930           1 :         status = cli_locktype(
    2931             :                 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    2932           1 :         if (!NT_STATUS_IS_OK(status)) {
    2933           0 :                 d_fprintf(stderr,
    2934             :                           "cli_locktype failed: %s\n",
    2935             :                           nt_errstr(status));
    2936           0 :                 goto done;
    2937             :         }
    2938             : 
    2939           1 :         lck = (struct smb1_lock_element) {
    2940           1 :                 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
    2941             :         };
    2942             : 
    2943           1 :         reqs[0] = cli_lockingx_create(
    2944             :                 ev,                             /* mem_ctx */
    2945             :                 ev,                             /* tevent_context */
    2946             :                 cli1,                           /* cli */
    2947             :                 fnum1,                          /* fnum */
    2948             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    2949             :                 0,                              /* newoplocklevel */
    2950             :                 1,                              /* timeout */
    2951             :                 0,                              /* num_unlocks */
    2952             :                 NULL,                           /* unlocks */
    2953             :                 1,                              /* num_locks */
    2954             :                 &lck,                               /* locks */
    2955             :                 &smbreqs[0]);                       /* psmbreq */
    2956           1 :         if (reqs[0] == NULL) {
    2957           0 :                 d_fprintf(stderr, "cli_lockingx_create failed\n");
    2958           0 :                 goto done;
    2959             :         }
    2960           1 :         tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
    2961             : 
    2962           1 :         reqs[1] = cli_read_andx_create(
    2963             :                 ev,             /* mem_ctx */
    2964             :                 ev,             /* ev */
    2965             :                 cli1,           /* cli */
    2966             :                 fnum1,          /* fnum */
    2967             :                 0,              /* offset */
    2968             :                 1,              /* size */
    2969             :                 &smbreqs[1]);       /* psmbreq */
    2970           1 :         if (reqs[1] == NULL) {
    2971           0 :                 d_fprintf(stderr, "cli_read_andx_create failed\n");
    2972           0 :                 goto done;
    2973             :         }
    2974           1 :         tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
    2975             : 
    2976           1 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
    2977           1 :         if (!NT_STATUS_IS_OK(status)) {
    2978           0 :                 d_fprintf(stderr,
    2979             :                           "smb1cli_req_chain_submit failed: %s\n",
    2980             :                           nt_errstr(status));
    2981           0 :                 goto done;
    2982             :         }
    2983             : 
    2984           7 :         while (!state.done) {
    2985           5 :                 tevent_loop_once(ev);
    2986             :         }
    2987             : 
    2988           1 :         torture_close_connection(cli1);
    2989             : 
    2990           1 :         if (state.ok) {
    2991           1 :                 ret = true;
    2992             :         }
    2993           1 : done:
    2994           1 :         return ret;
    2995             : }
    2996             : 
    2997           1 : static void locktest10_lockingx_done(struct tevent_req *subreq)
    2998             : {
    2999           1 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3000             :         NTSTATUS status;
    3001             : 
    3002           1 :         status = cli_lockingx_recv(subreq);
    3003           1 :         TALLOC_FREE(subreq);
    3004             : 
    3005           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3006           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3007           0 :                 state->ok = false;
    3008             :         }
    3009           1 : }
    3010             : 
    3011           1 : static void locktest10_read_andx_done(struct tevent_req *subreq)
    3012             : {
    3013           1 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3014           1 :         ssize_t received = -1;
    3015           1 :         uint8_t *rcvbuf = NULL;
    3016             :         NTSTATUS status;
    3017             : 
    3018           1 :         status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3019             : 
    3020           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
    3021           0 :                 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
    3022           0 :                 state->ok = false;
    3023             :         }
    3024             : 
    3025           1 :         state->done = true;
    3026           1 :         TALLOC_FREE(subreq);
    3027           1 : }
    3028             : 
    3029           1 : static bool run_locktest11(int dummy)
    3030             : {
    3031             :         struct cli_state *cli1;
    3032           1 :         const char *fname = "\\lockt11.lck";
    3033             :         NTSTATUS status;
    3034             :         uint16_t fnum;
    3035           1 :         bool ret = false;
    3036             : 
    3037           1 :         if (!torture_open_connection(&cli1, 0)) {
    3038           0 :                 return false;
    3039             :         }
    3040             : 
    3041           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3042             : 
    3043           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3044             : 
    3045           1 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
    3046           1 :         if (!NT_STATUS_IS_OK(status)) {
    3047           0 :                 d_fprintf(stderr,
    3048             :                           "cli_openx returned %s\n",
    3049             :                           nt_errstr(status));
    3050           0 :                 return false;
    3051             :         }
    3052             : 
    3053             :         /*
    3054             :          * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
    3055             :          * returns NT_STATUS_OK
    3056             :          */
    3057             : 
    3058           1 :         status = cli_lockingx(
    3059             :                 cli1,                           /* cli */
    3060             :                 fnum,                           /* fnum */
    3061             :                 LOCKING_ANDX_CANCEL_LOCK,       /* typeoflock */
    3062             :                 0,                              /* newoplocklevel */
    3063             :                 0,                              /* timeout */
    3064             :                 0,                              /* num_unlocks */
    3065             :                 NULL,                           /* unlocks */
    3066             :                 0,                              /* num_locks */
    3067             :                 NULL);                          /* locks */
    3068             : 
    3069           1 :         if (!NT_STATUS_IS_OK(status)) {
    3070           1 :                 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
    3071           1 :                 goto fail;
    3072             :         }
    3073             : 
    3074           0 :         ret = true;
    3075           1 : fail:
    3076           1 :         cli_close(cli1, fnum);
    3077           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3078             : 
    3079           1 :         return ret;
    3080             : }
    3081             : 
    3082             : struct deferred_close_state {
    3083             :         struct tevent_context *ev;
    3084             :         struct cli_state *cli;
    3085             :         uint16_t fnum;
    3086             : };
    3087             : 
    3088             : static void deferred_close_waited(struct tevent_req *subreq);
    3089             : static void deferred_close_done(struct tevent_req *subreq);
    3090             : 
    3091           1 : static struct tevent_req *deferred_close_send(
    3092             :         TALLOC_CTX *mem_ctx,
    3093             :         struct tevent_context *ev,
    3094             :         int wait_secs,
    3095             :         struct cli_state *cli,
    3096             :         uint16_t fnum)
    3097             : {
    3098           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    3099           1 :         struct deferred_close_state *state = NULL;
    3100           1 :         struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
    3101             : 
    3102           1 :         req = tevent_req_create(
    3103             :                 mem_ctx, &state, struct deferred_close_state);
    3104           1 :         if (req == NULL) {
    3105           0 :                 return NULL;
    3106             :         }
    3107           1 :         state->ev = ev;
    3108           1 :         state->cli = cli;
    3109           1 :         state->fnum = fnum;
    3110             : 
    3111           1 :         subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
    3112           1 :         if (tevent_req_nomem(subreq, req)) {
    3113           0 :                 return tevent_req_post(req, ev);
    3114             :         }
    3115           1 :         tevent_req_set_callback(subreq, deferred_close_waited, req);
    3116           1 :         return req;
    3117             : }
    3118             : 
    3119           1 : static void deferred_close_waited(struct tevent_req *subreq)
    3120             : {
    3121           1 :         struct tevent_req *req = tevent_req_callback_data(
    3122             :                 subreq, struct tevent_req);
    3123           1 :         struct deferred_close_state *state = tevent_req_data(
    3124             :                 req, struct deferred_close_state);
    3125             :         bool ok;
    3126             : 
    3127           1 :         ok = tevent_wakeup_recv(subreq);
    3128           1 :         TALLOC_FREE(subreq);
    3129           1 :         if (!ok) {
    3130           0 :                 tevent_req_oom(req);
    3131           0 :                 return;
    3132             :         }
    3133             : 
    3134           1 :         subreq = cli_close_send(state, state->ev, state->cli, state->fnum);
    3135           1 :         if (tevent_req_nomem(subreq, req)) {
    3136           0 :                 return;
    3137             :         }
    3138           1 :         tevent_req_set_callback(subreq, deferred_close_done, req);
    3139             : }
    3140             : 
    3141           1 : static void deferred_close_done(struct tevent_req *subreq)
    3142             : {
    3143           1 :         NTSTATUS status = cli_close_recv(subreq);
    3144           1 :         tevent_req_simple_finish_ntstatus(subreq, status);
    3145           1 : }
    3146             : 
    3147           1 : static NTSTATUS deferred_close_recv(struct tevent_req *req)
    3148             : {
    3149           1 :         return tevent_req_simple_recv_ntstatus(req);
    3150             : }
    3151             : 
    3152             : struct lockread_state {
    3153             :         struct smb1_lock_element lck;
    3154             :         struct tevent_req *reqs[2];
    3155             :         struct tevent_req *smbreqs[2];
    3156             :         NTSTATUS lock_status;
    3157             :         NTSTATUS read_status;
    3158             :         uint8_t *readbuf;
    3159             : };
    3160             : 
    3161             : static void lockread_lockingx_done(struct tevent_req *subreq);
    3162             : static void lockread_read_andx_done(struct tevent_req *subreq);
    3163             : 
    3164           1 : static struct tevent_req *lockread_send(
    3165             :         TALLOC_CTX *mem_ctx,
    3166             :         struct tevent_context *ev,
    3167             :         struct cli_state *cli,
    3168             :         uint16_t fnum)
    3169             : {
    3170           1 :         struct tevent_req *req = NULL;
    3171           1 :         struct lockread_state *state = NULL;
    3172             :         NTSTATUS status;
    3173             : 
    3174           1 :         req = tevent_req_create(mem_ctx, &state, struct lockread_state);
    3175           1 :         if (req == NULL) {
    3176           0 :                 return NULL;
    3177             :         }
    3178             : 
    3179           2 :         state->lck = (struct smb1_lock_element) {
    3180           1 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3181             :         };
    3182             : 
    3183           2 :         state->reqs[0] = cli_lockingx_create(
    3184             :                 ev,                             /* mem_ctx */
    3185             :                 ev,                             /* tevent_context */
    3186             :                 cli,                            /* cli */
    3187             :                 fnum,                           /* fnum */
    3188             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3189             :                 0,                              /* newoplocklevel */
    3190             :                 10000,                          /* timeout */
    3191             :                 0,                              /* num_unlocks */
    3192             :                 NULL,                           /* unlocks */
    3193             :                 1,                              /* num_locks */
    3194           1 :                 &state->lck,                     /* locks */
    3195           1 :                 &state->smbreqs[0]);             /* psmbreq */
    3196           1 :         if (tevent_req_nomem(state->reqs[0], req)) {
    3197           0 :                 return tevent_req_post(req, ev);
    3198             :         }
    3199           1 :         tevent_req_set_callback(
    3200           1 :                 state->reqs[0], lockread_lockingx_done, req);
    3201             : 
    3202           1 :         state->reqs[1] = cli_read_andx_create(
    3203             :                 ev,             /* mem_ctx */
    3204             :                 ev,             /* ev */
    3205             :                 cli,            /* cli */
    3206             :                 fnum,           /* fnum */
    3207             :                 0,              /* offset */
    3208             :                 1,              /* size */
    3209           1 :                 &state->smbreqs[1]);     /* psmbreq */
    3210           1 :         if (tevent_req_nomem(state->reqs[1], req)) {
    3211           0 :                 return tevent_req_post(req, ev);
    3212             :         }
    3213           1 :         tevent_req_set_callback(
    3214           1 :                 state->reqs[1], lockread_read_andx_done, req);
    3215             : 
    3216           1 :         status = smb1cli_req_chain_submit(state->smbreqs, 2);
    3217           1 :         if (tevent_req_nterror(req, status)) {
    3218           0 :                 return tevent_req_post(req, ev);
    3219             :         }
    3220           1 :         return req;
    3221             : }
    3222             : 
    3223           1 : static void lockread_lockingx_done(struct tevent_req *subreq)
    3224             : {
    3225           1 :         struct tevent_req *req = tevent_req_callback_data(
    3226             :                 subreq, struct tevent_req);
    3227           1 :         struct lockread_state *state = tevent_req_data(
    3228             :                 req, struct lockread_state);
    3229           1 :         state->lock_status = cli_lockingx_recv(subreq);
    3230           1 :         TALLOC_FREE(subreq);
    3231           1 :         d_fprintf(stderr,
    3232             :                   "lockingx returned %s\n",
    3233             :                   nt_errstr(state->lock_status));
    3234           1 : }
    3235             : 
    3236           1 : static void lockread_read_andx_done(struct tevent_req *subreq)
    3237             : {
    3238           1 :         struct tevent_req *req = tevent_req_callback_data(
    3239             :                 subreq, struct tevent_req);
    3240           1 :         struct lockread_state *state = tevent_req_data(
    3241             :                 req, struct lockread_state);
    3242           1 :         ssize_t received = -1;
    3243           1 :         uint8_t *rcvbuf = NULL;
    3244             : 
    3245           1 :         state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3246             : 
    3247           1 :         d_fprintf(stderr,
    3248             :                   "read returned %s\n",
    3249             :                   nt_errstr(state->read_status));
    3250             : 
    3251           1 :         if (!NT_STATUS_IS_OK(state->read_status)) {
    3252           0 :                 TALLOC_FREE(subreq);
    3253           0 :                 tevent_req_done(req);
    3254           0 :                 return;
    3255             :         }
    3256             : 
    3257           1 :         if (received > 0) {
    3258           1 :                 state->readbuf = talloc_memdup(state, rcvbuf, received);
    3259           1 :                 TALLOC_FREE(subreq);
    3260           1 :                 if (tevent_req_nomem(state->readbuf, req)) {
    3261           0 :                         return;
    3262             :                 }
    3263             :         }
    3264           1 :         TALLOC_FREE(subreq);
    3265           1 :         tevent_req_done(req);
    3266             : }
    3267             : 
    3268           1 : static NTSTATUS lockread_recv(
    3269             :         struct tevent_req *req,
    3270             :         NTSTATUS *lock_status,
    3271             :         NTSTATUS *read_status,
    3272             :         TALLOC_CTX *mem_ctx,
    3273             :         uint8_t **read_buf)
    3274             : {
    3275           1 :         struct lockread_state *state = tevent_req_data(
    3276             :                 req, struct lockread_state);
    3277             :         NTSTATUS status;
    3278             : 
    3279           1 :         if (tevent_req_is_nterror(req, &status)) {
    3280           0 :                 return status;
    3281             :         }
    3282             : 
    3283           1 :         *lock_status = state->lock_status;
    3284           1 :         *read_status = state->read_status;
    3285           1 :         if (state->readbuf != NULL) {
    3286           1 :                 *read_buf = talloc_move(mem_ctx, &state->readbuf);
    3287             :         } else {
    3288           0 :                 *read_buf = NULL;
    3289             :         }
    3290             : 
    3291           1 :         return NT_STATUS_OK;
    3292             : }
    3293             : 
    3294             : struct lock12_state {
    3295             :         uint8_t dummy;
    3296             : };
    3297             : 
    3298             : static void lock12_closed(struct tevent_req *subreq);
    3299             : static void lock12_read(struct tevent_req *subreq);
    3300             : 
    3301           1 : static struct tevent_req *lock12_send(
    3302             :         TALLOC_CTX *mem_ctx,
    3303             :         struct tevent_context *ev,
    3304             :         struct cli_state *cli,
    3305             :         uint16_t fnum1,
    3306             :         uint16_t fnum2)
    3307             : {
    3308           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    3309           1 :         struct lock12_state *state = NULL;
    3310             : 
    3311           1 :         req = tevent_req_create(mem_ctx, &state, struct lock12_state);
    3312           1 :         if (req == NULL) {
    3313           0 :                 return NULL;
    3314             :         }
    3315             : 
    3316           1 :         subreq = deferred_close_send(state, ev, 1, cli, fnum1);
    3317           1 :         if (tevent_req_nomem(subreq, req)) {
    3318           0 :                 return tevent_req_post(req, ev);
    3319             :         }
    3320           1 :         tevent_req_set_callback(subreq, lock12_closed, req);
    3321             : 
    3322           1 :         subreq = lockread_send(state, ev, cli, fnum2);
    3323           1 :         if (tevent_req_nomem(subreq, req)) {
    3324           0 :                 return tevent_req_post(req, ev);
    3325             :         }
    3326           1 :         tevent_req_set_callback(subreq, lock12_read, req);
    3327             : 
    3328           1 :         return req;
    3329             : }
    3330             : 
    3331           1 : static void lock12_closed(struct tevent_req *subreq)
    3332             : {
    3333           1 :         struct tevent_req *req = tevent_req_callback_data(
    3334             :                 subreq, struct tevent_req);
    3335             :         NTSTATUS status;
    3336             : 
    3337           1 :         status = deferred_close_recv(subreq);
    3338           1 :         TALLOC_FREE(subreq);
    3339           1 :         DBG_DEBUG("close returned %s\n", nt_errstr(status));
    3340           1 :         if (tevent_req_nterror(req, status)) {
    3341           0 :                 return;
    3342             :         }
    3343             : }
    3344             : 
    3345           1 : static void lock12_read(struct tevent_req *subreq)
    3346             : {
    3347           1 :         struct tevent_req *req = tevent_req_callback_data(
    3348             :                 subreq, struct tevent_req);
    3349           1 :         struct lock12_state *state = tevent_req_data(
    3350             :                 req, struct lock12_state);
    3351             :         NTSTATUS status, lock_status, read_status;
    3352           1 :         uint8_t *buf = NULL;
    3353             : 
    3354           1 :         status = lockread_recv(
    3355             :                 subreq, &lock_status, &read_status, state, &buf);
    3356           1 :         TALLOC_FREE(subreq);
    3357           2 :         if (tevent_req_nterror(req, status) ||
    3358           2 :             tevent_req_nterror(req, lock_status) ||
    3359           1 :             tevent_req_nterror(req, read_status)) {
    3360           0 :                 return;
    3361             :         }
    3362           1 :         tevent_req_done(req);
    3363             : }
    3364             : 
    3365           1 : static NTSTATUS lock12_recv(struct tevent_req *req)
    3366             : 
    3367             : {
    3368             :         NTSTATUS status;
    3369             : 
    3370           1 :         if (tevent_req_is_nterror(req, &status)) {
    3371           0 :                 return status;
    3372             :         }
    3373           1 :         return NT_STATUS_OK;
    3374             : }
    3375             : 
    3376           1 : static bool run_locktest12(int dummy)
    3377             : {
    3378           1 :         struct tevent_context *ev = NULL;
    3379           1 :         struct tevent_req *req = NULL;
    3380           1 :         struct cli_state *cli = NULL;
    3381           1 :         const char fname[] = "\\lockt12.lck";
    3382             :         uint16_t fnum1, fnum2;
    3383           1 :         bool ret = false;
    3384             :         bool ok;
    3385           1 :         uint8_t data = 1;
    3386             :         NTSTATUS status;
    3387             : 
    3388           1 :         printf("starting locktest12\n");
    3389             : 
    3390           1 :         ev = samba_tevent_context_init(NULL);
    3391           1 :         if (ev == NULL) {
    3392           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3393           0 :                 goto done;
    3394             :         }
    3395             : 
    3396           1 :         ok = torture_open_connection(&cli, 0);
    3397           1 :         if (!ok) {
    3398           0 :                 goto done;
    3399             :         }
    3400           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3401             : 
    3402           1 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3403           1 :         if (!NT_STATUS_IS_OK(status)) {
    3404           0 :                 d_fprintf(stderr,
    3405             :                           "cli_openx failed: %s\n",
    3406             :                           nt_errstr(status));
    3407           0 :                 goto done;
    3408             :         }
    3409             : 
    3410           1 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3411           1 :         if (!NT_STATUS_IS_OK(status)) {
    3412           0 :                 d_fprintf(stderr,
    3413             :                           "cli_openx failed: %s\n",
    3414             :                           nt_errstr(status));
    3415           0 :                 goto done;
    3416             :         }
    3417             : 
    3418           1 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3419           1 :         if (!NT_STATUS_IS_OK(status)) {
    3420           0 :                 d_fprintf(stderr,
    3421             :                           "cli_writeall failed: %s\n",
    3422             :                           nt_errstr(status));
    3423           0 :                 goto done;
    3424             :         }
    3425             : 
    3426           1 :         status = cli_locktype(
    3427             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3428           1 :         if (!NT_STATUS_IS_OK(status)) {
    3429           0 :                 d_fprintf(stderr,
    3430             :                           "cli_locktype failed: %s\n",
    3431             :                           nt_errstr(status));
    3432           0 :                 goto done;
    3433             :         }
    3434             : 
    3435           1 :         req = lock12_send(ev, ev, cli, fnum1, fnum2);
    3436           1 :         if (req == NULL) {
    3437           0 :                 d_fprintf(stderr, "lock12_send failed\n");
    3438           0 :                 goto done;
    3439             :         }
    3440             : 
    3441           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3442           1 :         if (!ok) {
    3443           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3444           0 :                 goto done;
    3445             :         }
    3446             : 
    3447           1 :         if (!NT_STATUS_IS_OK(status)) {
    3448           0 :                 d_fprintf(stderr,
    3449             :                           "tevent_req_poll_ntstatus returned %s\n",
    3450             :                           nt_errstr(status));
    3451           0 :                 goto done;
    3452             :         }
    3453             : 
    3454           1 :         status = lock12_recv(req);
    3455           1 :         if (!NT_STATUS_IS_OK(status)) {
    3456           0 :                 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
    3457           0 :                 goto done;
    3458             :         }
    3459             : 
    3460           1 :         ret = true;
    3461           1 : done:
    3462           1 :         if (cli != NULL) {
    3463           1 :                 torture_close_connection(cli);
    3464             :         }
    3465           1 :         return ret;
    3466             : }
    3467             : 
    3468             : struct lock_ntcancel_state {
    3469             :         struct timeval start;
    3470             :         struct smb1_lock_element lck;
    3471             :         struct tevent_req *subreq;
    3472             : };
    3473             : 
    3474             : static void lock_ntcancel_waited(struct tevent_req *subreq);
    3475             : static void lock_ntcancel_done(struct tevent_req *subreq);
    3476             : 
    3477           1 : static struct tevent_req *lock_ntcancel_send(
    3478             :         TALLOC_CTX *mem_ctx,
    3479             :         struct tevent_context *ev,
    3480             :         struct cli_state *cli,
    3481             :         uint16_t fnum)
    3482             : {
    3483           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    3484           1 :         struct lock_ntcancel_state *state = NULL;
    3485             : 
    3486           1 :         req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
    3487           1 :         if (req == NULL) {
    3488           0 :                 return NULL;
    3489             :         }
    3490           2 :         state->lck = (struct smb1_lock_element) {
    3491           1 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3492             :         };
    3493           1 :         state->start = timeval_current();
    3494             : 
    3495           1 :         state->subreq = cli_lockingx_send(
    3496             :                 state,                          /* mem_ctx */
    3497             :                 ev,                             /* tevent_context */
    3498             :                 cli,                            /* cli */
    3499             :                 fnum,                           /* fnum */
    3500             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3501             :                 0,                              /* newoplocklevel */
    3502             :                 10000,                          /* timeout */
    3503             :                 0,                              /* num_unlocks */
    3504             :                 NULL,                           /* unlocks */
    3505             :                 1,                              /* num_locks */
    3506           1 :                 &state->lck);                    /* locks */
    3507           1 :         if (tevent_req_nomem(state->subreq, req)) {
    3508           0 :                 return tevent_req_post(req, ev);
    3509             :         }
    3510           1 :         tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
    3511             : 
    3512           1 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
    3513           1 :         if (tevent_req_nomem(subreq, req)) {
    3514           0 :                 return tevent_req_post(req, ev);
    3515             :         }
    3516           1 :         tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
    3517           1 :         return req;
    3518             : }
    3519             : 
    3520           1 : static void lock_ntcancel_waited(struct tevent_req *subreq)
    3521             : {
    3522           1 :         struct tevent_req *req = tevent_req_callback_data(
    3523             :                 subreq, struct tevent_req);
    3524           1 :         struct lock_ntcancel_state *state = tevent_req_data(
    3525             :                 req, struct lock_ntcancel_state);
    3526             :         bool ok;
    3527             : 
    3528           1 :         ok = tevent_wakeup_recv(subreq);
    3529           1 :         TALLOC_FREE(subreq);
    3530           1 :         if (!ok) {
    3531           0 :                 tevent_req_oom(req);
    3532           0 :                 return;
    3533             :         }
    3534             : 
    3535           1 :         ok = tevent_req_cancel(state->subreq);
    3536           1 :         if (!ok) {
    3537           0 :                 d_fprintf(stderr, "Could not cancel subreq\n");
    3538           0 :                 tevent_req_oom(req);
    3539           0 :                 return;
    3540             :         }
    3541             : }
    3542             : 
    3543           1 : static void lock_ntcancel_done(struct tevent_req *subreq)
    3544             : {
    3545           1 :         struct tevent_req *req = tevent_req_callback_data(
    3546             :                 subreq, struct tevent_req);
    3547           1 :         struct lock_ntcancel_state *state = tevent_req_data(
    3548             :                 req, struct lock_ntcancel_state);
    3549             :         NTSTATUS status;
    3550             :         double elapsed;
    3551             : 
    3552           1 :         status = cli_lockingx_recv(subreq);
    3553           1 :         TALLOC_FREE(subreq);
    3554             : 
    3555           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3556           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3557           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3558           0 :                 return;
    3559             :         }
    3560             : 
    3561           1 :         elapsed = timeval_elapsed(&state->start);
    3562             : 
    3563           1 :         if (elapsed > 3) {
    3564           0 :                 d_printf("cli_lockingx was too slow, cancel did not work\n");
    3565           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3566           0 :                 return;
    3567             :         }
    3568             : 
    3569           1 :         tevent_req_done(req);
    3570             : }
    3571             : 
    3572           1 : static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
    3573             : {
    3574           1 :         return tevent_req_simple_recv_ntstatus(req);
    3575             : }
    3576             : 
    3577           1 : static bool run_locktest13(int dummy)
    3578             : {
    3579           1 :         struct tevent_context *ev = NULL;
    3580           1 :         struct tevent_req *req = NULL;
    3581           1 :         struct cli_state *cli = NULL;
    3582           1 :         const char fname[] = "\\lockt13.lck";
    3583             :         uint16_t fnum1, fnum2;
    3584           1 :         bool ret = false;
    3585             :         bool ok;
    3586           1 :         uint8_t data = 1;
    3587             :         NTSTATUS status;
    3588             : 
    3589           1 :         printf("starting locktest13\n");
    3590             : 
    3591           1 :         ev = samba_tevent_context_init(NULL);
    3592           1 :         if (ev == NULL) {
    3593           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3594           0 :                 goto done;
    3595             :         }
    3596             : 
    3597           1 :         ok = torture_open_connection(&cli, 0);
    3598           1 :         if (!ok) {
    3599           0 :                 goto done;
    3600             :         }
    3601           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3602             : 
    3603           1 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3604           1 :         if (!NT_STATUS_IS_OK(status)) {
    3605           0 :                 d_fprintf(stderr,
    3606             :                           "cli_openx failed: %s\n",
    3607             :                           nt_errstr(status));
    3608           0 :                 goto done;
    3609             :         }
    3610             : 
    3611           1 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3612           1 :         if (!NT_STATUS_IS_OK(status)) {
    3613           0 :                 d_fprintf(stderr,
    3614             :                           "cli_openx failed: %s\n",
    3615             :                           nt_errstr(status));
    3616           0 :                 goto done;
    3617             :         }
    3618             : 
    3619           1 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3620           1 :         if (!NT_STATUS_IS_OK(status)) {
    3621           0 :                 d_fprintf(stderr,
    3622             :                           "cli_writeall failed: %s\n",
    3623             :                           nt_errstr(status));
    3624           0 :                 goto done;
    3625             :         }
    3626             : 
    3627           1 :         status = cli_locktype(
    3628             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3629           1 :         if (!NT_STATUS_IS_OK(status)) {
    3630           0 :                 d_fprintf(stderr,
    3631             :                           "cli_locktype failed: %s\n",
    3632             :                           nt_errstr(status));
    3633           0 :                 goto done;
    3634             :         }
    3635             : 
    3636           1 :         req = lock_ntcancel_send(ev, ev, cli, fnum2);
    3637           1 :         if (req == NULL) {
    3638           0 :                 d_fprintf(stderr, "lock_ntcancel_send failed\n");
    3639           0 :                 goto done;
    3640             :         }
    3641             : 
    3642           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3643           1 :         if (!ok) {
    3644           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3645           0 :                 goto done;
    3646             :         }
    3647             : 
    3648           1 :         if (!NT_STATUS_IS_OK(status)) {
    3649           0 :                 d_fprintf(stderr,
    3650             :                           "tevent_req_poll_ntstatus returned %s\n",
    3651             :                           nt_errstr(status));
    3652           0 :                 goto done;
    3653             :         }
    3654             : 
    3655           1 :         status = lock_ntcancel_recv(req);
    3656           1 :         if (!NT_STATUS_IS_OK(status)) {
    3657           0 :                 d_fprintf(stderr,
    3658             :                           "lock_ntcancel returned %s\n",
    3659             :                           nt_errstr(status));
    3660           0 :                 goto done;
    3661             :         }
    3662             : 
    3663           1 :         ret = true;
    3664           1 : done:
    3665           1 :         if (cli != NULL) {
    3666           1 :                 torture_close_connection(cli);
    3667             :         }
    3668           1 :         return ret;
    3669             : }
    3670             : 
    3671             : /*
    3672             : test whether fnums and tids open on one VC are available on another (a major
    3673             : security hole)
    3674             : */
    3675           1 : static bool run_fdpasstest(int dummy)
    3676             : {
    3677             :         struct cli_state *cli1, *cli2;
    3678           1 :         const char *fname = "\\fdpass.tst";
    3679             :         uint16_t fnum1;
    3680             :         char buf[1024];
    3681             :         NTSTATUS status;
    3682             : 
    3683           1 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    3684           0 :                 return False;
    3685             :         }
    3686           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3687           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    3688             : 
    3689           1 :         printf("starting fdpasstest\n");
    3690             : 
    3691           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3692             : 
    3693           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    3694             :                           &fnum1);
    3695           1 :         if (!NT_STATUS_IS_OK(status)) {
    3696           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3697           0 :                 return False;
    3698             :         }
    3699             : 
    3700           1 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
    3701             :                               13, NULL);
    3702           1 :         if (!NT_STATUS_IS_OK(status)) {
    3703           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3704           0 :                 return False;
    3705             :         }
    3706             : 
    3707           1 :         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
    3708           1 :         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
    3709           1 :         cli_setpid(cli2, cli_getpid(cli1));
    3710             : 
    3711           1 :         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
    3712           0 :                 printf("read succeeded! nasty security hole [%s]\n", buf);
    3713           0 :                 return false;
    3714             :         }
    3715             : 
    3716           1 :         cli_close(cli1, fnum1);
    3717           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3718             : 
    3719           1 :         torture_close_connection(cli1);
    3720           1 :         torture_close_connection(cli2);
    3721             : 
    3722           1 :         printf("finished fdpasstest\n");
    3723           1 :         return True;
    3724             : }
    3725             : 
    3726           1 : static bool run_fdsesstest(int dummy)
    3727             : {
    3728             :         struct cli_state *cli;
    3729             :         uint16_t new_vuid;
    3730             :         uint16_t saved_vuid;
    3731             :         uint32_t new_cnum;
    3732             :         uint32_t saved_cnum;
    3733           1 :         const char *fname = "\\fdsess.tst";
    3734           1 :         const char *fname1 = "\\fdsess1.tst";
    3735             :         uint16_t fnum1;
    3736             :         uint16_t fnum2;
    3737             :         char buf[1024];
    3738           1 :         bool ret = True;
    3739             :         NTSTATUS status;
    3740             : 
    3741           1 :         if (!torture_open_connection(&cli, 0))
    3742           0 :                 return False;
    3743           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3744             : 
    3745           1 :         if (!torture_cli_session_setup2(cli, &new_vuid))
    3746           0 :                 return False;
    3747             : 
    3748           1 :         saved_cnum = cli_state_get_tid(cli);
    3749           1 :         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
    3750           0 :                 return False;
    3751           1 :         new_cnum = cli_state_get_tid(cli);
    3752           1 :         cli_state_set_tid(cli, saved_cnum);
    3753             : 
    3754           1 :         printf("starting fdsesstest\n");
    3755             : 
    3756           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3757           1 :         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3758             : 
    3759           1 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    3760           1 :         if (!NT_STATUS_IS_OK(status)) {
    3761           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3762           0 :                 return False;
    3763             :         }
    3764             : 
    3765           1 :         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
    3766             :                               NULL);
    3767           1 :         if (!NT_STATUS_IS_OK(status)) {
    3768           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3769           0 :                 return False;
    3770             :         }
    3771             : 
    3772           1 :         saved_vuid = cli_state_get_uid(cli);
    3773           1 :         cli_state_set_uid(cli, new_vuid);
    3774             : 
    3775           1 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3776           0 :                 printf("read succeeded with different vuid! "
    3777             :                        "nasty security hole [%s]\n", buf);
    3778           0 :                 ret = false;
    3779             :         }
    3780             :         /* Try to open a file with different vuid, samba cnum. */
    3781           1 :         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
    3782           1 :                 printf("create with different vuid, same cnum succeeded.\n");
    3783           1 :                 cli_close(cli, fnum2);
    3784           1 :                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3785             :         } else {
    3786           0 :                 printf("create with different vuid, same cnum failed.\n");
    3787           0 :                 printf("This will cause problems with service clients.\n");
    3788           0 :                 ret = False;
    3789             :         }
    3790             : 
    3791           1 :         cli_state_set_uid(cli, saved_vuid);
    3792             : 
    3793             :         /* Try with same vuid, different cnum. */
    3794           1 :         cli_state_set_tid(cli, new_cnum);
    3795             : 
    3796           1 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3797           0 :                 printf("read succeeded with different cnum![%s]\n", buf);
    3798           0 :                 ret = false;
    3799             :         }
    3800             : 
    3801           1 :         cli_state_set_tid(cli, saved_cnum);
    3802           1 :         cli_close(cli, fnum1);
    3803           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3804             : 
    3805           1 :         torture_close_connection(cli);
    3806             : 
    3807           1 :         printf("finished fdsesstest\n");
    3808           1 :         return ret;
    3809             : }
    3810             : 
    3811             : /*
    3812             :   This test checks that 
    3813             : 
    3814             :   1) the server does not allow an unlink on a file that is open
    3815             : */
    3816           1 : static bool run_unlinktest(int dummy)
    3817             : {
    3818             :         struct cli_state *cli;
    3819           1 :         const char *fname = "\\unlink.tst";
    3820             :         uint16_t fnum;
    3821           1 :         bool correct = True;
    3822             :         NTSTATUS status;
    3823             : 
    3824           1 :         if (!torture_open_connection(&cli, 0)) {
    3825           0 :                 return False;
    3826             :         }
    3827             : 
    3828           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3829             : 
    3830           1 :         printf("starting unlink test\n");
    3831             : 
    3832           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3833             : 
    3834           1 :         cli_setpid(cli, 1);
    3835             : 
    3836           1 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    3837           1 :         if (!NT_STATUS_IS_OK(status)) {
    3838           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3839           0 :                 return False;
    3840             :         }
    3841             : 
    3842           1 :         status = cli_unlink(cli, fname,
    3843             :                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3844           1 :         if (NT_STATUS_IS_OK(status)) {
    3845           0 :                 printf("error: server allowed unlink on an open file\n");
    3846           0 :                 correct = False;
    3847             :         } else {
    3848           1 :                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
    3849           1 :                                       NT_STATUS_SHARING_VIOLATION);
    3850             :         }
    3851             : 
    3852           1 :         cli_close(cli, fnum);
    3853           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3854             : 
    3855           1 :         if (!torture_close_connection(cli)) {
    3856           0 :                 correct = False;
    3857             :         }
    3858             : 
    3859           1 :         printf("unlink test finished\n");
    3860             : 
    3861           1 :         return correct;
    3862             : }
    3863             : 
    3864             : 
    3865             : /*
    3866             : test how many open files this server supports on the one socket
    3867             : */
    3868           0 : static bool run_maxfidtest(int dummy)
    3869             : {
    3870             :         struct cli_state *cli;
    3871             :         fstring fname;
    3872             :         uint16_t fnums[0x11000];
    3873             :         int i;
    3874           0 :         int retries=4;
    3875           0 :         bool correct = True;
    3876             :         NTSTATUS status;
    3877             : 
    3878           0 :         cli = current_cli;
    3879             : 
    3880           0 :         if (retries <= 0) {
    3881           0 :                 printf("failed to connect\n");
    3882           0 :                 return False;
    3883             :         }
    3884             : 
    3885           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3886             : 
    3887           0 :         for (i=0; i<0x11000; i++) {
    3888           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3889           0 :                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
    3890             :                                   &fnums[i]);
    3891           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3892           0 :                         printf("open of %s failed (%s)\n", 
    3893             :                                fname, nt_errstr(status));
    3894           0 :                         printf("maximum fnum is %d\n", i);
    3895           0 :                         break;
    3896             :                 }
    3897           0 :                 printf("%6d\r", i);
    3898             :         }
    3899           0 :         printf("%6d\n", i);
    3900           0 :         i--;
    3901             : 
    3902           0 :         printf("cleaning up\n");
    3903           0 :         for (;i>=0;i--) {
    3904           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3905           0 :                 cli_close(cli, fnums[i]);
    3906             : 
    3907           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3908           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3909           0 :                         printf("unlink of %s failed (%s)\n", 
    3910             :                                fname, nt_errstr(status));
    3911           0 :                         correct = False;
    3912             :                 }
    3913           0 :                 printf("%6d\r", i);
    3914             :         }
    3915           0 :         printf("%6d\n", 0);
    3916             : 
    3917           0 :         printf("maxfid test finished\n");
    3918           0 :         if (!torture_close_connection(cli)) {
    3919           0 :                 correct = False;
    3920             :         }
    3921           0 :         return correct;
    3922             : }
    3923             : 
    3924             : /* generate a random buffer */
    3925           0 : static void rand_buf(char *buf, int len)
    3926             : {
    3927           0 :         while (len--) {
    3928           0 :                 *buf = (char)sys_random();
    3929           0 :                 buf++;
    3930             :         }
    3931           0 : }
    3932             : 
    3933             : /* send smb negprot commands, not reading the response */
    3934           0 : static bool run_negprot_nowait(int dummy)
    3935             : {
    3936             :         struct tevent_context *ev;
    3937             :         int i;
    3938             :         struct cli_state *cli;
    3939           0 :         bool correct = True;
    3940             : 
    3941           0 :         printf("starting negprot nowait test\n");
    3942             : 
    3943           0 :         ev = samba_tevent_context_init(talloc_tos());
    3944           0 :         if (ev == NULL) {
    3945           0 :                 return false;
    3946             :         }
    3947             : 
    3948           0 :         if (!(cli = open_nbt_connection())) {
    3949           0 :                 TALLOC_FREE(ev);
    3950           0 :                 return False;
    3951             :         }
    3952             : 
    3953           0 :         for (i=0;i<50000;i++) {
    3954             :                 struct tevent_req *req;
    3955             : 
    3956           0 :                 req = smbXcli_negprot_send(
    3957             :                         ev,
    3958             :                         ev,
    3959             :                         cli->conn,
    3960           0 :                         cli->timeout,
    3961             :                         PROTOCOL_CORE,
    3962             :                         PROTOCOL_NT1,
    3963             :                         0,
    3964             :                         NULL);
    3965           0 :                 if (req == NULL) {
    3966           0 :                         TALLOC_FREE(ev);
    3967           0 :                         return false;
    3968             :                 }
    3969           0 :                 if (!tevent_req_poll(req, ev)) {
    3970           0 :                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
    3971           0 :                                   strerror(errno));
    3972           0 :                         TALLOC_FREE(ev);
    3973           0 :                         return false;
    3974             :                 }
    3975           0 :                 TALLOC_FREE(req);
    3976             :         }
    3977             : 
    3978           0 :         if (torture_close_connection(cli)) {
    3979           0 :                 correct = False;
    3980             :         }
    3981             : 
    3982           0 :         printf("finished negprot nowait test\n");
    3983             : 
    3984           0 :         return correct;
    3985             : }
    3986             : 
    3987             : /* send smb negprot commands, not reading the response */
    3988           0 : static bool run_bad_nbt_session(int dummy)
    3989             : {
    3990             :         struct nmb_name called, calling;
    3991             :         struct sockaddr_storage ss;
    3992             :         NTSTATUS status;
    3993             :         int fd;
    3994             :         bool ret;
    3995             : 
    3996           0 :         printf("starting bad nbt session test\n");
    3997             : 
    3998           0 :         make_nmb_name(&calling, myname, 0x0);
    3999           0 :         make_nmb_name(&called , host, 0x20);
    4000             : 
    4001           0 :         if (!resolve_name(host, &ss, 0x20, true)) {
    4002           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
    4003           0 :                 return false;
    4004             :         }
    4005             : 
    4006           0 :         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
    4007           0 :         if (!NT_STATUS_IS_OK(status)) {
    4008           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4009             :                           nt_errstr(status));
    4010           0 :                 return false;
    4011             :         }
    4012             : 
    4013           0 :         ret = cli_bad_session_request(fd, &calling, &called);
    4014           0 :         close(fd);
    4015           0 :         if (!ret) {
    4016           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4017             :                           nt_errstr(status));
    4018           0 :                 return false;
    4019             :         }
    4020             : 
    4021           0 :         printf("finished bad nbt session test\n");
    4022           0 :         return true;
    4023             : }
    4024             : 
    4025             : /* send random IPC commands */
    4026           0 : static bool run_randomipc(int dummy)
    4027             : {
    4028           0 :         char *rparam = NULL;
    4029           0 :         char *rdata = NULL;
    4030             :         unsigned int rdrcnt,rprcnt;
    4031             :         char param[1024];
    4032             :         int api, param_len, i;
    4033             :         struct cli_state *cli;
    4034           0 :         bool correct = True;
    4035           0 :         int count = 50000;
    4036             : 
    4037           0 :         printf("starting random ipc test\n");
    4038             : 
    4039           0 :         if (!torture_open_connection(&cli, 0)) {
    4040           0 :                 return False;
    4041             :         }
    4042             : 
    4043           0 :         for (i=0;i<count;i++) {
    4044           0 :                 api = sys_random() % 500;
    4045           0 :                 param_len = (sys_random() % 64);
    4046             : 
    4047           0 :                 rand_buf(param, param_len);
    4048             : 
    4049           0 :                 SSVAL(param,0,api); 
    4050             : 
    4051           0 :                 cli_api(cli, 
    4052             :                         param, param_len, 8,  
    4053             :                         NULL, 0, CLI_BUFFER_SIZE,
    4054             :                         &rparam, &rprcnt,     
    4055             :                         &rdata, &rdrcnt);
    4056           0 :                 if (i % 100 == 0) {
    4057           0 :                         printf("%d/%d\r", i,count);
    4058             :                 }
    4059             :         }
    4060           0 :         printf("%d/%d\n", i, count);
    4061             : 
    4062           0 :         if (!torture_close_connection(cli)) {
    4063           0 :                 correct = False;
    4064             :         }
    4065             : 
    4066           0 :         SAFE_FREE(rparam);
    4067           0 :         SAFE_FREE(rdata);
    4068             : 
    4069           0 :         printf("finished random ipc test\n");
    4070             : 
    4071           0 :         return correct;
    4072             : }
    4073             : 
    4074             : 
    4075             : 
    4076           0 : static void browse_callback(const char *sname, uint32_t stype,
    4077             :                             const char *comment, void *state)
    4078             : {
    4079           0 :         printf("\t%20.20s %08x %s\n", sname, stype, comment);
    4080           0 : }
    4081             : 
    4082             : 
    4083             : 
    4084             : /*
    4085             :   This test checks the browse list code
    4086             : 
    4087             : */
    4088           1 : static bool run_browsetest(int dummy)
    4089             : {
    4090             :         static struct cli_state *cli;
    4091           1 :         bool correct = True;
    4092             : 
    4093           1 :         printf("starting browse test\n");
    4094             : 
    4095           1 :         if (!torture_open_connection(&cli, 0)) {
    4096           0 :                 return False;
    4097             :         }
    4098             : 
    4099           1 :         printf("domain list:\n");
    4100           1 :         cli_NetServerEnum(cli, cli->server_domain, 
    4101             :                           SV_TYPE_DOMAIN_ENUM,
    4102             :                           browse_callback, NULL);
    4103             : 
    4104           1 :         printf("machine list:\n");
    4105           1 :         cli_NetServerEnum(cli, cli->server_domain, 
    4106             :                           SV_TYPE_ALL,
    4107             :                           browse_callback, NULL);
    4108             : 
    4109           1 :         if (!torture_close_connection(cli)) {
    4110           0 :                 correct = False;
    4111             :         }
    4112             : 
    4113           1 :         printf("browse test finished\n");
    4114             : 
    4115           1 :         return correct;
    4116             : 
    4117             : }
    4118             : 
    4119           4 : static bool check_attributes(struct cli_state *cli,
    4120             :                                 const char *fname,
    4121             :                                 uint32_t expected_attrs)
    4122             : {
    4123           4 :         uint32_t attrs = 0;
    4124           4 :         NTSTATUS status = cli_getatr(cli,
    4125             :                                 fname,
    4126             :                                 &attrs,
    4127             :                                 NULL,
    4128             :                                 NULL);
    4129           4 :         if (!NT_STATUS_IS_OK(status)) {
    4130           0 :                 printf("cli_getatr failed with %s\n",
    4131             :                         nt_errstr(status));
    4132           0 :                 return false;
    4133             :         }
    4134           4 :         if (attrs != expected_attrs) {
    4135           0 :                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
    4136             :                         (unsigned int)attrs,
    4137             :                         (unsigned int)expected_attrs);
    4138           0 :                 return false;
    4139             :         }
    4140           4 :         return true;
    4141             : }
    4142             : 
    4143             : /*
    4144             :   This checks how the getatr calls works
    4145             : */
    4146           1 : static bool run_attrtest(int dummy)
    4147             : {
    4148             :         struct cli_state *cli;
    4149             :         uint16_t fnum;
    4150             :         time_t t, t2;
    4151           1 :         const char *fname = "\\attrib123456789.tst";
    4152           1 :         bool correct = True;
    4153             :         NTSTATUS status;
    4154             : 
    4155           1 :         printf("starting attrib test\n");
    4156             : 
    4157           1 :         if (!torture_open_connection(&cli, 0)) {
    4158           0 :                 return False;
    4159             :         }
    4160             : 
    4161             :         /* Ensure we can't unlink with out-of-range (unknown) attribute. */
    4162           1 :         status = cli_unlink(cli, fname, 0x20000);
    4163           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4164           0 :                 correct = false;
    4165           0 :                 goto out;
    4166             :         }
    4167             : 
    4168           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4169           1 :         cli_openx(cli, fname, 
    4170             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4171           1 :         cli_close(cli, fnum);
    4172             : 
    4173           1 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4174           1 :         if (!NT_STATUS_IS_OK(status)) {
    4175           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4176           0 :                 correct = False;
    4177             :         }
    4178             : 
    4179           1 :         if (labs(t - time(NULL)) > 60*60*24*10) {
    4180           0 :                 printf("ERROR: SMBgetatr bug. time is %s",
    4181             :                        ctime(&t));
    4182           0 :                 t = time(NULL);
    4183           0 :                 correct = True;
    4184             :         }
    4185             : 
    4186           1 :         t2 = t-60*60*24; /* 1 day ago */
    4187             : 
    4188             :         /* Ensure we can't set with out-of-range (unknown) attribute. */
    4189           1 :         status = cli_setatr(cli, fname, 0x20000, t2);
    4190           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4191           0 :                 correct = false;
    4192           0 :                 goto out;
    4193             :         }
    4194             : 
    4195           1 :         status = cli_setatr(cli, fname, 0, t2);
    4196           1 :         if (!NT_STATUS_IS_OK(status)) {
    4197           0 :                 printf("setatr failed (%s)\n", nt_errstr(status));
    4198           0 :                 correct = True;
    4199             :         }
    4200             : 
    4201           1 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4202           1 :         if (!NT_STATUS_IS_OK(status)) {
    4203           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4204           0 :                 correct = True;
    4205             :         }
    4206             : 
    4207           1 :         if (t != t2) {
    4208           0 :                 printf("ERROR: getatr/setatr bug. times are\n%s",
    4209             :                        ctime(&t));
    4210           0 :                 printf("%s", ctime(&t2));
    4211           0 :                 correct = True;
    4212             :         }
    4213             : 
    4214           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4215             : 
    4216             :         /* Check cli_setpathinfo_ext() */
    4217             :         /* Re-create the file. */
    4218           1 :         status = cli_openx(cli, fname,
    4219             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4220           1 :         if (!NT_STATUS_IS_OK(status)) {
    4221           0 :                 printf("Failed to recreate %s (%s)\n",
    4222             :                         fname, nt_errstr(status));
    4223           0 :                 correct = false;
    4224             :         }
    4225           1 :         cli_close(cli, fnum);
    4226             : 
    4227           1 :         status = cli_setpathinfo_ext(
    4228             :                 cli,
    4229             :                 fname,
    4230           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4231           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4232           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4233           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4234             :                 FILE_ATTRIBUTE_SYSTEM |
    4235             :                 FILE_ATTRIBUTE_HIDDEN |
    4236             :                 FILE_ATTRIBUTE_READONLY);
    4237           1 :         if (!NT_STATUS_IS_OK(status)) {
    4238           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4239             :                         nt_errstr(status));
    4240           0 :                 correct = false;
    4241             :         }
    4242             : 
    4243             :         /* Check attributes are correct. */
    4244           1 :         correct = check_attributes(cli,
    4245             :                         fname,
    4246             :                         FILE_ATTRIBUTE_SYSTEM |
    4247             :                         FILE_ATTRIBUTE_HIDDEN |
    4248             :                         FILE_ATTRIBUTE_READONLY);
    4249           1 :         if (correct == false) {
    4250           0 :                 goto out;
    4251             :         }
    4252             : 
    4253             :         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
    4254           1 :         status = cli_setpathinfo_ext(
    4255             :                 cli,
    4256             :                 fname,
    4257           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4258           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4259           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4260           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4261             :                 FILE_ATTRIBUTE_NORMAL);
    4262           1 :         if (!NT_STATUS_IS_OK(status)) {
    4263           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4264             :                         nt_errstr(status));
    4265           0 :                 correct = false;
    4266             :         }
    4267             : 
    4268             :         /* Check attributes are correct. */
    4269           1 :         correct = check_attributes(cli,
    4270             :                         fname,
    4271             :                         FILE_ATTRIBUTE_SYSTEM |
    4272             :                         FILE_ATTRIBUTE_HIDDEN |
    4273             :                         FILE_ATTRIBUTE_READONLY);
    4274           1 :         if (correct == false) {
    4275           0 :                 goto out;
    4276             :         }
    4277             : 
    4278             :         /* Setting to (uint16_t)-1 should also be ignored. */
    4279           1 :         status = cli_setpathinfo_ext(
    4280             :                 cli,
    4281             :                 fname,
    4282           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4283           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4284           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4285           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4286             :                 (uint32_t)-1);
    4287           1 :         if (!NT_STATUS_IS_OK(status)) {
    4288           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4289             :                         nt_errstr(status));
    4290           0 :                 correct = false;
    4291             :         }
    4292             : 
    4293             :         /* Check attributes are correct. */
    4294           1 :         correct = check_attributes(cli,
    4295             :                         fname,
    4296             :                         FILE_ATTRIBUTE_SYSTEM |
    4297             :                         FILE_ATTRIBUTE_HIDDEN |
    4298             :                         FILE_ATTRIBUTE_READONLY);
    4299           1 :         if (correct == false) {
    4300           0 :                 goto out;
    4301             :         }
    4302             : 
    4303             :         /* Setting to 0 should clear them all. */
    4304           1 :         status = cli_setpathinfo_ext(
    4305             :                 cli,
    4306             :                 fname,
    4307           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4308           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4309           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4310           1 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4311             :                 0);
    4312           1 :         if (!NT_STATUS_IS_OK(status)) {
    4313           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4314             :                         nt_errstr(status));
    4315           0 :                 correct = false;
    4316             :         }
    4317             : 
    4318             :         /* Check attributes are correct. */
    4319           1 :         correct = check_attributes(cli,
    4320             :                         fname,
    4321             :                         FILE_ATTRIBUTE_NORMAL);
    4322           1 :         if (correct == false) {
    4323           0 :                 goto out;
    4324             :         }
    4325             : 
    4326           2 :   out:
    4327             : 
    4328           1 :         cli_unlink(cli,
    4329             :                 fname,
    4330             :                 FILE_ATTRIBUTE_SYSTEM |
    4331             :                 FILE_ATTRIBUTE_HIDDEN|
    4332             :                 FILE_ATTRIBUTE_READONLY);
    4333             : 
    4334           1 :         if (!torture_close_connection(cli)) {
    4335           0 :                 correct = False;
    4336             :         }
    4337             : 
    4338           1 :         printf("attrib test finished\n");
    4339             : 
    4340           1 :         return correct;
    4341             : }
    4342             : 
    4343           1 : static NTSTATUS cli_qfilename(
    4344             :         struct cli_state *cli,
    4345             :         uint16_t fnum,
    4346             :         TALLOC_CTX *mem_ctx,
    4347             :         char **_name)
    4348             : {
    4349             :         uint16_t recv_flags2;
    4350             :         uint8_t *rdata;
    4351             :         uint32_t num_rdata;
    4352             :         NTSTATUS status;
    4353           1 :         char *name = NULL;
    4354             :         uint32_t namelen;
    4355             : 
    4356           1 :         status = cli_qfileinfo(talloc_tos(), cli, fnum,
    4357             :                                SMB_QUERY_FILE_NAME_INFO,
    4358             :                                4, CLI_BUFFER_SIZE, &recv_flags2,
    4359             :                                &rdata, &num_rdata);
    4360           1 :         if (!NT_STATUS_IS_OK(status)) {
    4361           0 :                 return status;
    4362             :         }
    4363             : 
    4364           1 :         namelen = IVAL(rdata, 0);
    4365           1 :         if (namelen > (num_rdata - 4)) {
    4366           0 :                 TALLOC_FREE(rdata);
    4367           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    4368             :         }
    4369             : 
    4370           2 :         pull_string_talloc(mem_ctx,
    4371             :                            (const char *)rdata,
    4372             :                            recv_flags2,
    4373             :                            &name,
    4374           1 :                            rdata + 4,
    4375             :                            namelen,
    4376             :                            STR_UNICODE);
    4377           1 :         if (name == NULL) {
    4378           0 :                 status = map_nt_error_from_unix(errno);
    4379           0 :                 TALLOC_FREE(rdata);
    4380           0 :                 return status;
    4381             :         }
    4382             : 
    4383           1 :         *_name = name;
    4384           1 :         TALLOC_FREE(rdata);
    4385           1 :         return NT_STATUS_OK;
    4386             : }
    4387             : 
    4388             : /*
    4389             :   This checks a couple of trans2 calls
    4390             : */
    4391           1 : static bool run_trans2test(int dummy)
    4392             : {
    4393             :         struct cli_state *cli;
    4394             :         uint16_t fnum;
    4395             :         off_t size;
    4396             :         time_t c_time, a_time, m_time;
    4397             :         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
    4398           1 :         const char *fname = "\\trans2.tst";
    4399           1 :         const char *dname = "\\trans2";
    4400           1 :         const char *fname2 = "\\trans2\\trans2.tst";
    4401           1 :         char *pname = NULL;
    4402           1 :         bool correct = True;
    4403             :         NTSTATUS status;
    4404             :         uint32_t fs_attr;
    4405             :         uint64_t ino;
    4406             : 
    4407           1 :         printf("starting trans2 test\n");
    4408             : 
    4409           1 :         if (!torture_open_connection(&cli, 0)) {
    4410           0 :                 return False;
    4411             :         }
    4412             : 
    4413           1 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4414             :                 /* Ensure ino is zero, SMB2 gets a real one. */
    4415           0 :                 ino = 0;
    4416             :         } else {
    4417             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
    4418           1 :                 ino = (uint64_t)-1;
    4419             :         }
    4420             : 
    4421           1 :         status = cli_get_fs_attr_info(cli, &fs_attr);
    4422           1 :         if (!NT_STATUS_IS_OK(status)) {
    4423           0 :                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
    4424             :                        nt_errstr(status));
    4425           0 :                 correct = false;
    4426             :         }
    4427             : 
    4428           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4429           1 :         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4430           1 :         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
    4431             :                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
    4432           1 :         if (!NT_STATUS_IS_OK(status)) {
    4433           0 :                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
    4434           0 :                 correct = False;
    4435             :         }
    4436             : 
    4437           1 :         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
    4438           1 :         if (!NT_STATUS_IS_OK(status)) {
    4439           0 :                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
    4440           0 :                 correct = False;
    4441             :         }
    4442           1 :         else if (strcmp(pname, fname)) {
    4443           0 :                 printf("qfilename gave different name? [%s] [%s]\n",
    4444             :                        fname, pname);
    4445           0 :                 correct = False;
    4446             :         }
    4447             : 
    4448           1 :         cli_close(cli, fnum);
    4449             : 
    4450           1 :         sleep(2);
    4451             : 
    4452           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4453           1 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
    4454             :                           &fnum);
    4455           1 :         if (!NT_STATUS_IS_OK(status)) {
    4456           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4457           0 :                 return False;
    4458             :         }
    4459           1 :         cli_close(cli, fnum);
    4460             : 
    4461           1 :         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
    4462             :                                 NULL);
    4463           1 :         if (!NT_STATUS_IS_OK(status)) {
    4464           0 :                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
    4465           0 :                 correct = False;
    4466             :         } else {
    4467           1 :                 time_t t = time(NULL);
    4468             : 
    4469           1 :                 if (c_time != m_time) {
    4470           0 :                         printf("create time=%s", ctime(&c_time));
    4471           0 :                         printf("modify time=%s", ctime(&m_time));
    4472           0 :                         printf("This system appears to have sticky create times\n");
    4473             :                 }
    4474           1 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
    4475           0 :                         printf("access time=%s", ctime(&a_time));
    4476           0 :                         printf("This system appears to set a midnight access time\n");
    4477           0 :                         correct = False;
    4478             :                 }
    4479             : 
    4480           1 :                 if (labs(m_time - t) > 60*60*24*7) {
    4481           0 :                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
    4482           0 :                         correct = False;
    4483             :                 }
    4484             :         }
    4485             : 
    4486             : 
    4487           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4488           1 :         cli_openx(cli, fname, 
    4489             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4490           1 :         cli_close(cli, fnum);
    4491           1 :         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
    4492             :                                 &m_time_ts, &size, NULL, &ino);
    4493           1 :         if (!NT_STATUS_IS_OK(status)) {
    4494           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4495           0 :                 correct = False;
    4496             :         } else {
    4497           1 :                 if (w_time_ts.tv_sec < 60*60*24*2) {
    4498           0 :                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
    4499           0 :                         printf("This system appears to set a initial 0 write time\n");
    4500           0 :                         correct = False;
    4501             :                 }
    4502           1 :                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4503             :                         /* SMB2 should always return an inode. */
    4504           0 :                         if (ino == 0) {
    4505           0 :                                 printf("SMB2 bad inode (0)\n");
    4506           0 :                                 correct = false;
    4507             :                         }
    4508             :                 } else {
    4509             :                         /* SMB1 must always return zero here. */
    4510           1 :                         if (ino != 0) {
    4511           0 :                                 printf("SMB1 bad inode (!0)\n");
    4512           0 :                                 correct = false;
    4513             :                         }
    4514             :                 }
    4515             :         }
    4516             : 
    4517           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4518             : 
    4519             : 
    4520             :         /* check if the server updates the directory modification time
    4521             :            when creating a new file */
    4522           1 :         status = cli_mkdir(cli, dname);
    4523           1 :         if (!NT_STATUS_IS_OK(status)) {
    4524           0 :                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
    4525           0 :                 correct = False;
    4526             :         }
    4527           1 :         sleep(3);
    4528           1 :         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
    4529             :                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
    4530           1 :         if (!NT_STATUS_IS_OK(status)) {
    4531           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4532           0 :                 correct = False;
    4533             :         }
    4534             : 
    4535           1 :         cli_openx(cli, fname2, 
    4536             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4537           1 :         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
    4538           1 :         cli_close(cli, fnum);
    4539           1 :         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
    4540             :                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
    4541           1 :         if (!NT_STATUS_IS_OK(status)) {
    4542           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4543           0 :                 correct = False;
    4544             :         } else {
    4545           1 :                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
    4546             :                     == 0) {
    4547           0 :                         printf("This system does not update directory modification times\n");
    4548           0 :                         correct = False;
    4549             :                 }
    4550             :         }
    4551           1 :         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4552           1 :         cli_rmdir(cli, dname);
    4553             : 
    4554           1 :         if (!torture_close_connection(cli)) {
    4555           0 :                 correct = False;
    4556             :         }
    4557             : 
    4558           1 :         printf("trans2 test finished\n");
    4559             : 
    4560           1 :         return correct;
    4561             : }
    4562             : 
    4563             : /*
    4564             :   This checks new W2K calls.
    4565             : */
    4566             : 
    4567          36 : static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
    4568             : {
    4569          36 :         uint8_t *buf = NULL;
    4570             :         uint32_t len;
    4571             :         NTSTATUS status;
    4572             : 
    4573          36 :         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
    4574             :                                CLI_BUFFER_SIZE, NULL, &buf, &len);
    4575          36 :         if (!NT_STATUS_IS_OK(status)) {
    4576          36 :                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
    4577             :                        nt_errstr(status));
    4578             :         } else {
    4579           0 :                 printf("qfileinfo: level %d, len = %u\n", level, len);
    4580           0 :                 dump_data(0, (uint8_t *)buf, len);
    4581           0 :                 printf("\n");
    4582             :         }
    4583          36 :         TALLOC_FREE(buf);
    4584          36 :         return status;
    4585             : }
    4586             : 
    4587           1 : static bool run_w2ktest(int dummy)
    4588             : {
    4589             :         struct cli_state *cli;
    4590             :         uint16_t fnum;
    4591           1 :         const char *fname = "\\w2ktest\\w2k.tst";
    4592             :         int level;
    4593           1 :         bool correct = True;
    4594             : 
    4595           1 :         printf("starting w2k test\n");
    4596             : 
    4597           1 :         if (!torture_open_connection(&cli, 0)) {
    4598           0 :                 return False;
    4599             :         }
    4600             : 
    4601           1 :         cli_openx(cli, fname, 
    4602             :                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
    4603             : 
    4604          37 :         for (level = 1004; level < 1040; level++) {
    4605          36 :                 new_trans(cli, fnum, level);
    4606             :         }
    4607             : 
    4608           1 :         cli_close(cli, fnum);
    4609             : 
    4610           1 :         if (!torture_close_connection(cli)) {
    4611           0 :                 correct = False;
    4612             :         }
    4613             : 
    4614           1 :         printf("w2k test finished\n");
    4615             : 
    4616           1 :         return correct;
    4617             : }
    4618             : 
    4619             : 
    4620             : /*
    4621             :   this is a harness for some oplock tests
    4622             :  */
    4623           1 : static bool run_oplock1(int dummy)
    4624             : {
    4625             :         struct cli_state *cli1;
    4626           1 :         const char *fname = "\\lockt1.lck";
    4627             :         uint16_t fnum1;
    4628           1 :         bool correct = True;
    4629             :         NTSTATUS status;
    4630             : 
    4631           1 :         printf("starting oplock test 1\n");
    4632             : 
    4633           1 :         if (!torture_open_connection(&cli1, 0)) {
    4634           0 :                 return False;
    4635             :         }
    4636             : 
    4637           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4638             : 
    4639           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4640             : 
    4641           1 :         cli1->use_oplocks = True;
    4642             : 
    4643           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4644             :                           &fnum1);
    4645           1 :         if (!NT_STATUS_IS_OK(status)) {
    4646           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4647           0 :                 return False;
    4648             :         }
    4649             : 
    4650           1 :         cli1->use_oplocks = False;
    4651             : 
    4652           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4653           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4654             : 
    4655           1 :         status = cli_close(cli1, fnum1);
    4656           1 :         if (!NT_STATUS_IS_OK(status)) {
    4657           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4658           0 :                 return False;
    4659             :         }
    4660             : 
    4661           1 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4662           1 :         if (!NT_STATUS_IS_OK(status)) {
    4663           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4664           0 :                 return False;
    4665             :         }
    4666             : 
    4667           1 :         if (!torture_close_connection(cli1)) {
    4668           0 :                 correct = False;
    4669             :         }
    4670             : 
    4671           1 :         printf("finished oplock test 1\n");
    4672             : 
    4673           1 :         return correct;
    4674             : }
    4675             : 
    4676           0 : static bool run_oplock2(int dummy)
    4677             : {
    4678             :         struct cli_state *cli1, *cli2;
    4679           0 :         const char *fname = "\\lockt2.lck";
    4680             :         uint16_t fnum1, fnum2;
    4681           0 :         int saved_use_oplocks = use_oplocks;
    4682             :         char buf[4];
    4683           0 :         bool correct = True;
    4684             :         volatile bool *shared_correct;
    4685             :         size_t nread;
    4686             :         NTSTATUS status;
    4687             : 
    4688           0 :         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
    4689           0 :         *shared_correct = True;
    4690             : 
    4691           0 :         use_level_II_oplocks = True;
    4692           0 :         use_oplocks = True;
    4693             : 
    4694           0 :         printf("starting oplock test 2\n");
    4695             : 
    4696           0 :         if (!torture_open_connection(&cli1, 0)) {
    4697           0 :                 use_level_II_oplocks = False;
    4698           0 :                 use_oplocks = saved_use_oplocks;
    4699           0 :                 return False;
    4700             :         }
    4701             : 
    4702           0 :         if (!torture_open_connection(&cli2, 1)) {
    4703           0 :                 use_level_II_oplocks = False;
    4704           0 :                 use_oplocks = saved_use_oplocks;
    4705           0 :                 return False;
    4706             :         }
    4707             : 
    4708           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4709             : 
    4710           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4711           0 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4712             : 
    4713           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4714             :                           &fnum1);
    4715           0 :         if (!NT_STATUS_IS_OK(status)) {
    4716           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4717           0 :                 return False;
    4718             :         }
    4719             : 
    4720             :         /* Don't need the globals any more. */
    4721           0 :         use_level_II_oplocks = False;
    4722           0 :         use_oplocks = saved_use_oplocks;
    4723             : 
    4724           0 :         if (fork() == 0) {
    4725             :                 /* Child code */
    4726           0 :                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    4727           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4728           0 :                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
    4729           0 :                         *shared_correct = False;
    4730           0 :                         exit(0);
    4731             :                 }
    4732             : 
    4733           0 :                 sleep(2);
    4734             : 
    4735           0 :                 status = cli_close(cli2, fnum2);
    4736           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4737           0 :                         printf("close2 failed (%s)\n", nt_errstr(status));
    4738           0 :                         *shared_correct = False;
    4739             :                 }
    4740             : 
    4741           0 :                 exit(0);
    4742             :         }
    4743             : 
    4744           0 :         sleep(2);
    4745             : 
    4746             :         /* Ensure cli1 processes the break. Empty file should always return 0
    4747             :          * bytes.  */
    4748           0 :         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
    4749           0 :         if (!NT_STATUS_IS_OK(status)) {
    4750           0 :                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
    4751           0 :                 correct = false;
    4752           0 :         } else if (nread != 0) {
    4753           0 :                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
    4754             :                       (unsigned long)nread, 0);
    4755           0 :                 correct = false;
    4756             :         }
    4757             : 
    4758             :         /* Should now be at level II. */
    4759             :         /* Test if sending a write locks causes a break to none. */
    4760           0 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
    4761           0 :         if (!NT_STATUS_IS_OK(status)) {
    4762           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4763           0 :                 correct = False;
    4764             :         }
    4765             : 
    4766           0 :         cli_unlock(cli1, fnum1, 0, 4);
    4767             : 
    4768           0 :         sleep(2);
    4769             : 
    4770           0 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    4771           0 :         if (!NT_STATUS_IS_OK(status)) {
    4772           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4773           0 :                 correct = False;
    4774             :         }
    4775             : 
    4776           0 :         cli_unlock(cli1, fnum1, 0, 4);
    4777             : 
    4778           0 :         sleep(2);
    4779             : 
    4780           0 :         cli_read(cli1, fnum1, buf, 0, 4, NULL);
    4781             : 
    4782           0 :         status = cli_close(cli1, fnum1);
    4783           0 :         if (!NT_STATUS_IS_OK(status)) {
    4784           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4785           0 :                 correct = False;
    4786             :         }
    4787             : 
    4788           0 :         sleep(4);
    4789             : 
    4790           0 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4791           0 :         if (!NT_STATUS_IS_OK(status)) {
    4792           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4793           0 :                 correct = False;
    4794             :         }
    4795             : 
    4796           0 :         if (!torture_close_connection(cli1)) {
    4797           0 :                 correct = False;
    4798             :         }
    4799             : 
    4800           0 :         if (!*shared_correct) {
    4801           0 :                 correct = False;
    4802             :         }
    4803             : 
    4804           0 :         printf("finished oplock test 2\n");
    4805             : 
    4806           0 :         return correct;
    4807             : }
    4808             : 
    4809             : struct oplock4_state {
    4810             :         struct tevent_context *ev;
    4811             :         struct cli_state *cli;
    4812             :         bool *got_break;
    4813             :         uint16_t *fnum2;
    4814             : };
    4815             : 
    4816             : static void oplock4_got_break(struct tevent_req *req);
    4817             : static void oplock4_got_open(struct tevent_req *req);
    4818             : 
    4819           1 : static bool run_oplock4(int dummy)
    4820             : {
    4821             :         struct tevent_context *ev;
    4822             :         struct cli_state *cli1, *cli2;
    4823             :         struct tevent_req *oplock_req, *open_req;
    4824           1 :         const char *fname = "\\lockt4.lck";
    4825           1 :         const char *fname_ln = "\\lockt4_ln.lck";
    4826             :         uint16_t fnum1, fnum2;
    4827           1 :         int saved_use_oplocks = use_oplocks;
    4828             :         NTSTATUS status;
    4829           1 :         bool correct = true;
    4830             : 
    4831             :         bool got_break;
    4832             : 
    4833             :         struct oplock4_state *state;
    4834             : 
    4835           1 :         printf("starting oplock test 4\n");
    4836             : 
    4837           1 :         if (!torture_open_connection(&cli1, 0)) {
    4838           0 :                 use_level_II_oplocks = false;
    4839           0 :                 use_oplocks = saved_use_oplocks;
    4840           0 :                 return false;
    4841             :         }
    4842             : 
    4843           1 :         if (!torture_open_connection(&cli2, 1)) {
    4844           0 :                 use_level_II_oplocks = false;
    4845           0 :                 use_oplocks = saved_use_oplocks;
    4846           0 :                 return false;
    4847             :         }
    4848             : 
    4849           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4850           1 :         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4851             : 
    4852           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4853           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4854             : 
    4855             :         /* Create the file. */
    4856           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4857             :                           &fnum1);
    4858           1 :         if (!NT_STATUS_IS_OK(status)) {
    4859           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4860           0 :                 return false;
    4861             :         }
    4862             : 
    4863           1 :         status = cli_close(cli1, fnum1);
    4864           1 :         if (!NT_STATUS_IS_OK(status)) {
    4865           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4866           0 :                 return false;
    4867             :         }
    4868             : 
    4869             :         /* Now create a hardlink. */
    4870           1 :         status = cli_hardlink(cli1, fname, fname_ln);
    4871           1 :         if (!NT_STATUS_IS_OK(status)) {
    4872           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    4873           0 :                 return false;
    4874             :         }
    4875             : 
    4876             :         /* Prove that opening hardlinks cause deny modes to conflict. */
    4877           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
    4878           1 :         if (!NT_STATUS_IS_OK(status)) {
    4879           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4880           0 :                 return false;
    4881             :         }
    4882             : 
    4883           1 :         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
    4884           1 :         if (NT_STATUS_IS_OK(status)) {
    4885           0 :                 printf("open of %s succeeded - should fail with sharing violation.\n",
    4886             :                         fname_ln);
    4887           0 :                 return false;
    4888             :         }
    4889             : 
    4890           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    4891           0 :                 printf("open of %s should fail with sharing violation. Got %s\n",
    4892             :                         fname_ln, nt_errstr(status));
    4893           0 :                 return false;
    4894             :         }
    4895             : 
    4896           1 :         status = cli_close(cli1, fnum1);
    4897           1 :         if (!NT_STATUS_IS_OK(status)) {
    4898           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4899           0 :                 return false;
    4900             :         }
    4901             : 
    4902           1 :         cli1->use_oplocks = true;
    4903           1 :         cli2->use_oplocks = true;
    4904             : 
    4905           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    4906           1 :         if (!NT_STATUS_IS_OK(status)) {
    4907           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4908           0 :                 return false;
    4909             :         }
    4910             : 
    4911           1 :         ev = samba_tevent_context_init(talloc_tos());
    4912           1 :         if (ev == NULL) {
    4913           0 :                 printf("tevent_context_init failed\n");
    4914           0 :                 return false;
    4915             :         }
    4916             : 
    4917           1 :         state = talloc(ev, struct oplock4_state);
    4918           1 :         if (state == NULL) {
    4919           0 :                 printf("talloc failed\n");
    4920           0 :                 return false;
    4921             :         }
    4922           1 :         state->ev = ev;
    4923           1 :         state->cli = cli1;
    4924           1 :         state->got_break = &got_break;
    4925           1 :         state->fnum2 = &fnum2;
    4926             : 
    4927           1 :         oplock_req = cli_smb_oplock_break_waiter_send(
    4928             :                 talloc_tos(), ev, cli1);
    4929           1 :         if (oplock_req == NULL) {
    4930           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    4931           0 :                 return false;
    4932             :         }
    4933           1 :         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
    4934             : 
    4935           1 :         open_req = cli_openx_send(
    4936             :                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
    4937           1 :         if (open_req == NULL) {
    4938           0 :                 printf("cli_openx_send failed\n");
    4939           0 :                 return false;
    4940             :         }
    4941           1 :         tevent_req_set_callback(open_req, oplock4_got_open, state);
    4942             : 
    4943           1 :         got_break = false;
    4944           1 :         fnum2 = 0xffff;
    4945             : 
    4946           9 :         while (!got_break || fnum2 == 0xffff) {
    4947             :                 int ret;
    4948           7 :                 ret = tevent_loop_once(ev);
    4949           7 :                 if (ret == -1) {
    4950           0 :                         printf("tevent_loop_once failed: %s\n",
    4951           0 :                                strerror(errno));
    4952           0 :                         return false;
    4953             :                 }
    4954             :         }
    4955             : 
    4956           1 :         status = cli_close(cli2, fnum2);
    4957           1 :         if (!NT_STATUS_IS_OK(status)) {
    4958           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4959           0 :                 correct = false;
    4960             :         }
    4961             : 
    4962           1 :         status = cli_close(cli1, fnum1);
    4963           1 :         if (!NT_STATUS_IS_OK(status)) {
    4964           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4965           0 :                 correct = false;
    4966             :         }
    4967             : 
    4968           1 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4969           1 :         if (!NT_STATUS_IS_OK(status)) {
    4970           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4971           0 :                 correct = false;
    4972             :         }
    4973             : 
    4974           1 :         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4975           1 :         if (!NT_STATUS_IS_OK(status)) {
    4976           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4977           0 :                 correct = false;
    4978             :         }
    4979             : 
    4980           1 :         if (!torture_close_connection(cli1)) {
    4981           0 :                 correct = false;
    4982             :         }
    4983             : 
    4984           1 :         if (!got_break) {
    4985           0 :                 correct = false;
    4986             :         }
    4987             : 
    4988           1 :         printf("finished oplock test 4\n");
    4989             : 
    4990           1 :         return correct;
    4991             : }
    4992             : 
    4993           1 : static void oplock4_got_break(struct tevent_req *req)
    4994             : {
    4995           1 :         struct oplock4_state *state = tevent_req_callback_data(
    4996             :                 req, struct oplock4_state);
    4997             :         uint16_t fnum;
    4998             :         uint8_t level;
    4999             :         NTSTATUS status;
    5000             : 
    5001           1 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    5002           1 :         TALLOC_FREE(req);
    5003           1 :         if (!NT_STATUS_IS_OK(status)) {
    5004           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    5005             :                        nt_errstr(status));
    5006           0 :                 return;
    5007             :         }
    5008           1 :         *state->got_break = true;
    5009             : 
    5010           1 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    5011             :                                   NO_OPLOCK);
    5012           1 :         if (req == NULL) {
    5013           0 :                 printf("cli_oplock_ack_send failed\n");
    5014           0 :                 return;
    5015             :         }
    5016             : }
    5017             : 
    5018           1 : static void oplock4_got_open(struct tevent_req *req)
    5019             : {
    5020           1 :         struct oplock4_state *state = tevent_req_callback_data(
    5021             :                 req, struct oplock4_state);
    5022             :         NTSTATUS status;
    5023             : 
    5024           1 :         status = cli_openx_recv(req, state->fnum2);
    5025           1 :         if (!NT_STATUS_IS_OK(status)) {
    5026           0 :                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
    5027           0 :                 *state->fnum2 = 0xffff;
    5028             :         }
    5029           1 : }
    5030             : 
    5031             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
    5032             : 
    5033             : struct oplock5_state {
    5034             :         int pipe_down_fd;
    5035             : };
    5036             : 
    5037             : /*
    5038             :  * Async open the file that has a kernel oplock, do an echo to get
    5039             :  * that 100% across, close the file to signal to the child fd that the
    5040             :  * oplock can be dropped, wait for the open reply.
    5041             :  */
    5042             : 
    5043             : static void oplock5_opened(struct tevent_req *subreq);
    5044             : static void oplock5_pong(struct tevent_req *subreq);
    5045             : static void oplock5_timedout(struct tevent_req *subreq);
    5046             : 
    5047           0 : static struct tevent_req *oplock5_send(
    5048             :         TALLOC_CTX *mem_ctx,
    5049             :         struct tevent_context *ev,
    5050             :         struct cli_state *cli,
    5051             :         const char *fname,
    5052             :         int pipe_down_fd)
    5053             : {
    5054           0 :         struct tevent_req *req = NULL, *subreq = NULL;
    5055           0 :         struct oplock5_state *state = NULL;
    5056             :         static uint8_t data = 0;
    5057             : 
    5058           0 :         req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
    5059           0 :         if (req == NULL) {
    5060           0 :                 return NULL;
    5061             :         }
    5062           0 :         state->pipe_down_fd = pipe_down_fd;
    5063             : 
    5064           0 :         subreq = cli_ntcreate_send(
    5065             :                 state,
    5066             :                 ev,
    5067             :                 cli,
    5068             :                 fname,
    5069             :                 0,                      /* CreatFlags */
    5070             :                 SEC_FILE_READ_DATA,    /* DesiredAccess */
    5071             :                 FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
    5072             :                 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
    5073             :                 FILE_OPEN,               /* CreateDisposition */
    5074             :                 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
    5075             :                 0,                       /* Impersonation */
    5076             :                 0);                      /* SecurityFlags */
    5077           0 :         if (tevent_req_nomem(subreq, req)) {
    5078           0 :                 return tevent_req_post(req, ev);
    5079             :         }
    5080           0 :         tevent_req_set_callback(subreq, oplock5_opened, req);
    5081             : 
    5082           0 :         subreq = cli_echo_send(
    5083             :                 state,
    5084             :                 ev,
    5085             :                 cli,
    5086             :                 1,
    5087           0 :                 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
    5088           0 :         if (tevent_req_nomem(subreq, req)) {
    5089           0 :                 return tevent_req_post(req, ev);
    5090             :         }
    5091           0 :         tevent_req_set_callback(subreq, oplock5_pong, req);
    5092             : 
    5093           0 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
    5094           0 :         if (tevent_req_nomem(subreq, req)) {
    5095           0 :                 return tevent_req_post(req, ev);
    5096             :         }
    5097           0 :         tevent_req_set_callback(subreq, oplock5_timedout, req);
    5098             : 
    5099           0 :         return req;
    5100             : }
    5101             : 
    5102           0 : static void oplock5_opened(struct tevent_req *subreq)
    5103             : {
    5104           0 :         struct tevent_req *req = tevent_req_callback_data(
    5105             :                 subreq, struct tevent_req);
    5106             :         NTSTATUS status;
    5107             :         uint16_t fnum;
    5108             : 
    5109           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
    5110           0 :         TALLOC_FREE(subreq);
    5111           0 :         if (tevent_req_nterror(req, status)) {
    5112           0 :                 return;
    5113             :         }
    5114           0 :         tevent_req_done(req);
    5115             : }
    5116             : 
    5117           0 : static void oplock5_pong(struct tevent_req *subreq)
    5118             : {
    5119           0 :         struct tevent_req *req = tevent_req_callback_data(
    5120             :                 subreq, struct tevent_req);
    5121           0 :         struct oplock5_state *state = tevent_req_data(
    5122             :                 req, struct oplock5_state);
    5123             :         NTSTATUS status;
    5124             : 
    5125           0 :         status = cli_echo_recv(subreq);
    5126           0 :         TALLOC_FREE(subreq);
    5127           0 :         if (tevent_req_nterror(req, status)) {
    5128           0 :                 return;
    5129             :         }
    5130             : 
    5131           0 :         close(state->pipe_down_fd);
    5132             : }
    5133             : 
    5134           0 : static void oplock5_timedout(struct tevent_req *subreq)
    5135             : {
    5136           0 :         struct tevent_req *req = tevent_req_callback_data(
    5137             :                 subreq, struct tevent_req);
    5138             :         bool ok;
    5139             : 
    5140           0 :         ok = tevent_wakeup_recv(subreq);
    5141           0 :         TALLOC_FREE(subreq);
    5142           0 :         if (!ok) {
    5143           0 :                 tevent_req_oom(req);
    5144           0 :                 return;
    5145             :         }
    5146           0 :         tevent_req_nterror(req, NT_STATUS_TIMEOUT);
    5147             : }
    5148             : 
    5149           0 : static NTSTATUS oplock5_recv(struct tevent_req *req)
    5150             : {
    5151           0 :         return tevent_req_simple_recv_ntstatus(req);
    5152             : }
    5153             : 
    5154           0 : static bool run_oplock5(int dummy)
    5155             : {
    5156           0 :         struct tevent_context *ev = NULL;
    5157           0 :         struct tevent_req *req = NULL;
    5158           0 :         struct cli_state *cli = NULL;
    5159           0 :         const char *fname = "oplock5.txt";
    5160             :         int pipe_down[2], pipe_up[2];
    5161             :         pid_t child_pid;
    5162           0 :         uint8_t c = '\0';
    5163             :         NTSTATUS status;
    5164             :         int ret;
    5165             :         bool ok;
    5166             : 
    5167           0 :         printf("starting oplock5\n");
    5168             : 
    5169           0 :         if (local_path == NULL) {
    5170           0 :                 d_fprintf(stderr, "oplock5 must be given a local path via "
    5171             :                           "-l <localpath>\n");
    5172           0 :                 return false;
    5173             :         }
    5174             : 
    5175           0 :         ret = pipe(pipe_down);
    5176           0 :         if (ret == -1) {
    5177           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5178           0 :                 return false;
    5179             :         }
    5180           0 :         ret = pipe(pipe_up);
    5181           0 :         if (ret == -1) {
    5182           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5183           0 :                 return false;
    5184             :         }
    5185             : 
    5186           0 :         child_pid = fork();
    5187           0 :         if (child_pid == -1) {
    5188           0 :                 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
    5189           0 :                 return false;
    5190             :         }
    5191             : 
    5192           0 :         if (child_pid == 0) {
    5193           0 :                 char *local_file = NULL;
    5194             :                 int fd;
    5195             : 
    5196           0 :                 close(pipe_down[1]);
    5197           0 :                 close(pipe_up[0]);
    5198             : 
    5199           0 :                 local_file = talloc_asprintf(
    5200           0 :                         talloc_tos(), "%s/%s", local_path, fname);
    5201           0 :                 if (local_file == 0) {
    5202           0 :                         c = 1;
    5203           0 :                         goto do_write;
    5204             :                 }
    5205           0 :                 fd = open(local_file, O_RDWR|O_CREAT, 0644);
    5206           0 :                 if (fd == -1) {
    5207           0 :                         d_fprintf(stderr,
    5208             :                                   "open(%s) in child failed: %s\n",
    5209             :                                   local_file,
    5210           0 :                                   strerror(errno));
    5211           0 :                         c = 2;
    5212           0 :                         goto do_write;
    5213             :                 }
    5214             : 
    5215           0 :                 signal(SIGIO, SIG_IGN);
    5216             : 
    5217           0 :                 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
    5218           0 :                 if (ret == -1) {
    5219           0 :                         d_fprintf(stderr,
    5220             :                                   "SETLEASE in child failed: %s\n",
    5221           0 :                                   strerror(errno));
    5222           0 :                         c = 3;
    5223           0 :                         goto do_write;
    5224             :                 }
    5225             : 
    5226           0 :         do_write:
    5227           0 :                 ret = sys_write(pipe_up[1], &c, sizeof(c));
    5228           0 :                 if (ret == -1) {
    5229           0 :                         d_fprintf(stderr,
    5230             :                                   "sys_write failed: %s\n",
    5231           0 :                                   strerror(errno));
    5232           0 :                         exit(4);
    5233             :                 }
    5234           0 :                 ret = sys_read(pipe_down[0], &c, sizeof(c));
    5235           0 :                 if (ret == -1) {
    5236           0 :                         d_fprintf(stderr,
    5237             :                                   "sys_read failed: %s\n",
    5238           0 :                                   strerror(errno));
    5239           0 :                         exit(5);
    5240             :                 }
    5241           0 :                 exit(0);
    5242             :         }
    5243             : 
    5244           0 :         close(pipe_up[1]);
    5245           0 :         close(pipe_down[0]);
    5246             : 
    5247           0 :         ret = sys_read(pipe_up[0], &c, sizeof(c));
    5248           0 :         if (ret != 1) {
    5249           0 :                 d_fprintf(stderr,
    5250             :                           "sys_read failed: %s\n",
    5251           0 :                           strerror(errno));
    5252           0 :                 return false;
    5253             :         }
    5254           0 :         if (c != 0) {
    5255           0 :                 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
    5256           0 :                 return false;
    5257             :         }
    5258             : 
    5259           0 :         ok = torture_open_connection(&cli, 0);
    5260           0 :         if (!ok) {
    5261           0 :                 d_fprintf(stderr, "torture_open_connection failed\n");
    5262           0 :                 return false;
    5263             :         }
    5264             : 
    5265           0 :         ev = samba_tevent_context_init(talloc_tos());
    5266           0 :         if (ev == NULL) {
    5267           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5268           0 :                 return false;
    5269             :         }
    5270             : 
    5271           0 :         req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
    5272           0 :         if (req == NULL) {
    5273           0 :                 d_fprintf(stderr, "oplock5_send failed\n");
    5274           0 :                 return false;
    5275             :         }
    5276             : 
    5277           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5278           0 :         if (!ok) {
    5279           0 :                 d_fprintf(stderr,
    5280             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5281             :                           nt_errstr(status));
    5282           0 :                 return false;
    5283             :         }
    5284             : 
    5285           0 :         status = oplock5_recv(req);
    5286           0 :         TALLOC_FREE(req);
    5287           0 :         if (!NT_STATUS_IS_OK(status)) {
    5288           0 :                 d_fprintf(stderr,
    5289             :                           "oplock5 failed: %s\n",
    5290             :                           nt_errstr(status));
    5291           0 :                 return false;
    5292             :         }
    5293             : 
    5294           0 :         return true;
    5295             : }
    5296             : 
    5297             : #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
    5298             : 
    5299             : /*
    5300             :   Test delete on close semantics.
    5301             :  */
    5302           1 : static bool run_deletetest(int dummy)
    5303             : {
    5304           1 :         struct cli_state *cli1 = NULL;
    5305           1 :         struct cli_state *cli2 = NULL;
    5306           1 :         const char *fname = "\\delete.file";
    5307           1 :         uint16_t fnum1 = (uint16_t)-1;
    5308           1 :         uint16_t fnum2 = (uint16_t)-1;
    5309           1 :         bool correct = false;
    5310             :         NTSTATUS status;
    5311             : 
    5312           1 :         printf("starting delete test\n");
    5313             : 
    5314           1 :         if (!torture_open_connection(&cli1, 0)) {
    5315           0 :                 return False;
    5316             :         }
    5317             : 
    5318           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5319             : 
    5320             :         /* Test 1 - this should delete the file on close. */
    5321             : 
    5322           1 :         cli_setatr(cli1, fname, 0, 0);
    5323           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5324             : 
    5325           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5326             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5327             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5328           1 :         if (!NT_STATUS_IS_OK(status)) {
    5329           0 :                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
    5330           0 :                 goto fail;
    5331             :         }
    5332             : 
    5333           1 :         status = cli_close(cli1, fnum1);
    5334           1 :         if (!NT_STATUS_IS_OK(status)) {
    5335           0 :                 printf("[1] close failed (%s)\n", nt_errstr(status));
    5336           0 :                 goto fail;
    5337             :         }
    5338             : 
    5339           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    5340           1 :         if (NT_STATUS_IS_OK(status)) {
    5341           0 :                 printf("[1] open of %s succeeded (should fail)\n", fname);
    5342           0 :                 goto fail;
    5343             :         }
    5344             : 
    5345           1 :         printf("first delete on close test succeeded.\n");
    5346             : 
    5347             :         /* Test 2 - this should delete the file on close. */
    5348             : 
    5349           1 :         cli_setatr(cli1, fname, 0, 0);
    5350           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5351             : 
    5352           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5353             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5354             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5355           1 :         if (!NT_STATUS_IS_OK(status)) {
    5356           0 :                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
    5357           0 :                 goto fail;
    5358             :         }
    5359             : 
    5360           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5361           1 :         if (!NT_STATUS_IS_OK(status)) {
    5362           0 :                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5363           0 :                 goto fail;
    5364             :         }
    5365             : 
    5366           1 :         status = cli_close(cli1, fnum1);
    5367           1 :         if (!NT_STATUS_IS_OK(status)) {
    5368           0 :                 printf("[2] close failed (%s)\n", nt_errstr(status));
    5369           0 :                 goto fail;
    5370             :         }
    5371             : 
    5372           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5373           1 :         if (NT_STATUS_IS_OK(status)) {
    5374           0 :                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
    5375           0 :                 status = cli_close(cli1, fnum1);
    5376           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5377           0 :                         printf("[2] close failed (%s)\n", nt_errstr(status));
    5378             :                 }
    5379           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5380           0 :                 goto fail;
    5381             :         }
    5382             : 
    5383           1 :         printf("second delete on close test succeeded.\n");
    5384             : 
    5385             :         /* Test 3 - ... */
    5386           1 :         cli_setatr(cli1, fname, 0, 0);
    5387           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5388             : 
    5389           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5390             :                               FILE_ATTRIBUTE_NORMAL,
    5391             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5392             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5393           1 :         if (!NT_STATUS_IS_OK(status)) {
    5394           0 :                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5395           0 :                 goto fail;
    5396             :         }
    5397             : 
    5398             :         /* This should fail with a sharing violation - open for delete is only compatible
    5399             :            with SHARE_DELETE. */
    5400             : 
    5401           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5402             :                               FILE_ATTRIBUTE_NORMAL,
    5403             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5404             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5405           1 :         if (NT_STATUS_IS_OK(status)) {
    5406           0 :                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
    5407           0 :                 goto fail;
    5408             :         }
    5409             : 
    5410             :         /* This should succeed. */
    5411           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5412             :                              FILE_ATTRIBUTE_NORMAL,
    5413             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5414             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5415           1 :         if (!NT_STATUS_IS_OK(status)) {
    5416           0 :                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
    5417           0 :                 goto fail;
    5418             :         }
    5419             : 
    5420           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5421           1 :         if (!NT_STATUS_IS_OK(status)) {
    5422           0 :                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5423           0 :                 goto fail;
    5424             :         }
    5425             : 
    5426           1 :         status = cli_close(cli1, fnum1);
    5427           1 :         if (!NT_STATUS_IS_OK(status)) {
    5428           0 :                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
    5429           0 :                 goto fail;
    5430             :         }
    5431             : 
    5432           1 :         status = cli_close(cli1, fnum2);
    5433           1 :         if (!NT_STATUS_IS_OK(status)) {
    5434           0 :                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
    5435           0 :                 goto fail;
    5436             :         }
    5437             : 
    5438             :         /* This should fail - file should no longer be there. */
    5439             : 
    5440           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5441           1 :         if (NT_STATUS_IS_OK(status)) {
    5442           0 :                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
    5443           0 :                 status = cli_close(cli1, fnum1);
    5444           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5445           0 :                         printf("[3] close failed (%s)\n", nt_errstr(status));
    5446             :                 }
    5447           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5448           0 :                 goto fail;
    5449             :         }
    5450             : 
    5451           1 :         printf("third delete on close test succeeded.\n");
    5452             : 
    5453             :         /* Test 4 ... */
    5454           1 :         cli_setatr(cli1, fname, 0, 0);
    5455           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5456             : 
    5457           1 :         status = cli_ntcreate(cli1, fname, 0,
    5458             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5459             :                               FILE_ATTRIBUTE_NORMAL,
    5460             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5461             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5462           1 :         if (!NT_STATUS_IS_OK(status)) {
    5463           0 :                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
    5464           0 :                 goto fail;
    5465             :         }
    5466             : 
    5467             :         /* This should succeed. */
    5468           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5469             :                              FILE_ATTRIBUTE_NORMAL,
    5470             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5471             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5472           1 :         if (!NT_STATUS_IS_OK(status)) {
    5473           0 :                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5474           0 :                 goto fail;
    5475             :         }
    5476             : 
    5477           1 :         status = cli_close(cli1, fnum2);
    5478           1 :         if (!NT_STATUS_IS_OK(status)) {
    5479           0 :                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
    5480           0 :                 goto fail;
    5481             :         }
    5482             : 
    5483           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5484           1 :         if (!NT_STATUS_IS_OK(status)) {
    5485           0 :                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5486           0 :                 goto fail;
    5487             :         }
    5488             : 
    5489             :         /* This should fail - no more opens once delete on close set. */
    5490           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5491             :                               FILE_ATTRIBUTE_NORMAL,
    5492             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5493             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5494           1 :         if (NT_STATUS_IS_OK(status)) {
    5495           0 :                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
    5496           0 :                 goto fail;
    5497             :         }
    5498             : 
    5499           1 :         status = cli_close(cli1, fnum1);
    5500           1 :         if (!NT_STATUS_IS_OK(status)) {
    5501           0 :                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
    5502           0 :                 goto fail;
    5503             :         }
    5504             : 
    5505           1 :         printf("fourth delete on close test succeeded.\n");
    5506             : 
    5507             :         /* Test 5 ... */
    5508           1 :         cli_setatr(cli1, fname, 0, 0);
    5509           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5510             : 
    5511           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
    5512           1 :         if (!NT_STATUS_IS_OK(status)) {
    5513           0 :                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
    5514           0 :                 goto fail;
    5515             :         }
    5516             : 
    5517             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5518             : 
    5519           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5520           1 :         if (NT_STATUS_IS_OK(status)) {
    5521           0 :                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
    5522           0 :                 goto fail;
    5523             :         }
    5524             : 
    5525           1 :         status = cli_close(cli1, fnum1);
    5526           1 :         if (!NT_STATUS_IS_OK(status)) {
    5527           0 :                 printf("[5] close failed (%s)\n", nt_errstr(status));
    5528           0 :                 goto fail;
    5529             :         }
    5530             : 
    5531           1 :         printf("fifth delete on close test succeeded.\n");
    5532             : 
    5533             :         /* Test 6 ... */
    5534           1 :         cli_setatr(cli1, fname, 0, 0);
    5535           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5536             : 
    5537           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5538             :                              FILE_ATTRIBUTE_NORMAL,
    5539             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5540             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5541           1 :         if (!NT_STATUS_IS_OK(status)) {
    5542           0 :                 printf("[6] open of %s failed (%s)\n", fname,
    5543             :                        nt_errstr(status));
    5544           0 :                 goto fail;
    5545             :         }
    5546             : 
    5547             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5548             : 
    5549           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5550           1 :         if (NT_STATUS_IS_OK(status)) {
    5551           0 :                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
    5552           0 :                 goto fail;
    5553             :         }
    5554             : 
    5555           1 :         status = cli_close(cli1, fnum1);
    5556           1 :         if (!NT_STATUS_IS_OK(status)) {
    5557           0 :                 printf("[6] close failed (%s)\n", nt_errstr(status));
    5558           0 :                 goto fail;
    5559             :         }
    5560             : 
    5561           1 :         printf("sixth delete on close test succeeded.\n");
    5562             : 
    5563             :         /* Test 7 ... */
    5564           1 :         cli_setatr(cli1, fname, 0, 0);
    5565           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5566             : 
    5567           1 :         status = cli_ntcreate(cli1, fname, 0,
    5568             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5569             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5570             :                               0, 0, &fnum1, NULL);
    5571           1 :         if (!NT_STATUS_IS_OK(status)) {
    5572           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5573           0 :                 goto fail;
    5574             :         }
    5575             : 
    5576           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5577           1 :         if (!NT_STATUS_IS_OK(status)) {
    5578           0 :                 printf("[7] setting delete_on_close on file failed !\n");
    5579           0 :                 goto fail;
    5580             :         }
    5581             : 
    5582           1 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5583           1 :         if (!NT_STATUS_IS_OK(status)) {
    5584           0 :                 printf("[7] unsetting delete_on_close on file failed !\n");
    5585           0 :                 goto fail;
    5586             :         }
    5587             : 
    5588           1 :         status = cli_close(cli1, fnum1);
    5589           1 :         if (!NT_STATUS_IS_OK(status)) {
    5590           0 :                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
    5591           0 :                 goto fail;
    5592             :         }
    5593             : 
    5594             :         /* This next open should succeed - we reset the flag. */
    5595           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5596           1 :         if (!NT_STATUS_IS_OK(status)) {
    5597           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5598           0 :                 goto fail;
    5599             :         }
    5600             : 
    5601           1 :         status = cli_close(cli1, fnum1);
    5602           1 :         if (!NT_STATUS_IS_OK(status)) {
    5603           0 :                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
    5604           0 :                 goto fail;
    5605             :         }
    5606             : 
    5607           1 :         printf("seventh delete on close test succeeded.\n");
    5608             : 
    5609             :         /* Test 8 ... */
    5610           1 :         cli_setatr(cli1, fname, 0, 0);
    5611           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5612             : 
    5613           1 :         if (!torture_open_connection(&cli2, 1)) {
    5614           0 :                 printf("[8] failed to open second connection.\n");
    5615           0 :                 goto fail;
    5616             :         }
    5617             : 
    5618           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5619             : 
    5620           1 :         status = cli_ntcreate(cli1, fname, 0,
    5621             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5622             :                              FILE_ATTRIBUTE_NORMAL,
    5623             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5624             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5625           1 :         if (!NT_STATUS_IS_OK(status)) {
    5626           0 :                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5627           0 :                 goto fail;
    5628             :         }
    5629             : 
    5630           1 :         status = cli_ntcreate(cli2, fname, 0,
    5631             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5632             :                              FILE_ATTRIBUTE_NORMAL,
    5633             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5634             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5635           1 :         if (!NT_STATUS_IS_OK(status)) {
    5636           0 :                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5637           0 :                 goto fail;
    5638             :         }
    5639             : 
    5640           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5641           1 :         if (!NT_STATUS_IS_OK(status)) {
    5642           0 :                 printf("[8] setting delete_on_close on file failed !\n");
    5643           0 :                 goto fail;
    5644             :         }
    5645             : 
    5646           1 :         status = cli_close(cli1, fnum1);
    5647           1 :         if (!NT_STATUS_IS_OK(status)) {
    5648           0 :                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
    5649           0 :                 goto fail;
    5650             :         }
    5651             : 
    5652           1 :         status = cli_close(cli2, fnum2);
    5653           1 :         if (!NT_STATUS_IS_OK(status)) {
    5654           0 :                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
    5655           0 :                 goto fail;
    5656             :         }
    5657             : 
    5658             :         /* This should fail.. */
    5659           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5660           1 :         if (NT_STATUS_IS_OK(status)) {
    5661           0 :                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
    5662           0 :                 goto fail;
    5663             :         }
    5664             : 
    5665           1 :         printf("eighth delete on close test succeeded.\n");
    5666             : 
    5667             :         /* Test 9 ... */
    5668             : 
    5669             :         /* This should fail - we need to set DELETE_ACCESS. */
    5670           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5671             :                               FILE_ATTRIBUTE_NORMAL,
    5672             :                               FILE_SHARE_NONE,
    5673             :                               FILE_OVERWRITE_IF,
    5674             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5675           1 :         if (NT_STATUS_IS_OK(status)) {
    5676           0 :                 printf("[9] open of %s succeeded should have failed!\n", fname);
    5677           0 :                 goto fail;
    5678             :         }
    5679             : 
    5680           1 :         printf("ninth delete on close test succeeded.\n");
    5681             : 
    5682             :         /* Test 10 ... */
    5683             : 
    5684           1 :         status = cli_ntcreate(cli1, fname, 0,
    5685             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5686             :                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5687             :                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
    5688             :                              0, &fnum1, NULL);
    5689           1 :         if (!NT_STATUS_IS_OK(status)) {
    5690           0 :                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
    5691           0 :                 goto fail;
    5692             :         }
    5693             : 
    5694             :         /* This should delete the file. */
    5695           1 :         status = cli_close(cli1, fnum1);
    5696           1 :         if (!NT_STATUS_IS_OK(status)) {
    5697           0 :                 printf("[10] close failed (%s)\n", nt_errstr(status));
    5698           0 :                 goto fail;
    5699             :         }
    5700             : 
    5701             :         /* This should fail.. */
    5702           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5703           1 :         if (NT_STATUS_IS_OK(status)) {
    5704           0 :                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
    5705           0 :                 goto fail;
    5706             :         }
    5707             : 
    5708           1 :         printf("tenth delete on close test succeeded.\n");
    5709             : 
    5710             :         /* Test 11 ... */
    5711             : 
    5712           1 :         cli_setatr(cli1, fname, 0, 0);
    5713           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5714             : 
    5715             :         /* Can we open a read-only file with delete access? */
    5716             : 
    5717             :         /* Create a readonly file. */
    5718           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5719             :                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
    5720             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5721           1 :         if (!NT_STATUS_IS_OK(status)) {
    5722           0 :                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
    5723           0 :                 goto fail;
    5724             :         }
    5725             : 
    5726           1 :         status = cli_close(cli1, fnum1);
    5727           1 :         if (!NT_STATUS_IS_OK(status)) {
    5728           0 :                 printf("[11] close failed (%s)\n", nt_errstr(status));
    5729           0 :                 goto fail;
    5730             :         }
    5731             : 
    5732             :         /* Now try open for delete access. */
    5733           1 :         status = cli_ntcreate(cli1, fname, 0,
    5734             :                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
    5735             :                              0,
    5736             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5737             :                              FILE_OPEN, 0, 0, &fnum1, NULL);
    5738           1 :         if (!NT_STATUS_IS_OK(status)) {
    5739           0 :                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
    5740           0 :                 goto fail;
    5741             :         }
    5742             : 
    5743           1 :         cli_close(cli1, fnum1);
    5744             : 
    5745           1 :         printf("eleventh delete on close test succeeded.\n");
    5746             : 
    5747             :         /*
    5748             :          * Test 12
    5749             :          * like test 4 but with initial delete on close
    5750             :          */
    5751             : 
    5752           1 :         cli_setatr(cli1, fname, 0, 0);
    5753           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5754             : 
    5755           1 :         status = cli_ntcreate(cli1, fname, 0,
    5756             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5757             :                               FILE_ATTRIBUTE_NORMAL,
    5758             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5759             :                               FILE_OVERWRITE_IF,
    5760             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5761           1 :         if (!NT_STATUS_IS_OK(status)) {
    5762           0 :                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5763           0 :                 goto fail;
    5764             :         }
    5765             : 
    5766           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5767             :                               FILE_ATTRIBUTE_NORMAL,
    5768             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5769             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5770           1 :         if (!NT_STATUS_IS_OK(status)) {
    5771           0 :                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
    5772           0 :                 goto fail;
    5773             :         }
    5774             : 
    5775           1 :         status = cli_close(cli1, fnum2);
    5776           1 :         if (!NT_STATUS_IS_OK(status)) {
    5777           0 :                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
    5778           0 :                 goto fail;
    5779             :         }
    5780             : 
    5781           1 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5782           1 :         if (!NT_STATUS_IS_OK(status)) {
    5783           0 :                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5784           0 :                 goto fail;
    5785             :         }
    5786             : 
    5787             :         /* This should fail - no more opens once delete on close set. */
    5788           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5789             :                               FILE_ATTRIBUTE_NORMAL,
    5790             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5791             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5792           1 :         if (NT_STATUS_IS_OK(status)) {
    5793           0 :                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
    5794           0 :                 goto fail;
    5795             :         }
    5796             : 
    5797           1 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5798           1 :         if (!NT_STATUS_IS_OK(status)) {
    5799           0 :                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
    5800           0 :                 goto fail;
    5801             :         }
    5802             : 
    5803           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5804             :                               FILE_ATTRIBUTE_NORMAL,
    5805             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5806             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5807           1 :         if (!NT_STATUS_IS_OK(status)) {
    5808           0 :                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
    5809           0 :                 goto fail;
    5810             :         }
    5811             : 
    5812           1 :         status = cli_close(cli1, fnum2);
    5813           1 :         if (!NT_STATUS_IS_OK(status)) {
    5814           0 :                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
    5815           0 :                 goto fail;
    5816             :         }
    5817             : 
    5818           1 :         status = cli_close(cli1, fnum1);
    5819           1 :         if (!NT_STATUS_IS_OK(status)) {
    5820           0 :                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
    5821           0 :                 goto fail;
    5822             :         }
    5823             : 
    5824             :         /*
    5825             :          * setting delete on close on the handle does
    5826             :          * not unset the initial delete on close...
    5827             :          */
    5828           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5829             :                               FILE_ATTRIBUTE_NORMAL,
    5830             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5831             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5832           1 :         if (NT_STATUS_IS_OK(status)) {
    5833           0 :                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
    5834           0 :                 goto fail;
    5835           1 :         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5836           0 :                 printf("ntcreate returned %s, expected "
    5837             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
    5838             :                        nt_errstr(status));
    5839           0 :                 goto fail;
    5840             :         }
    5841             : 
    5842           1 :         printf("twelfth delete on close test succeeded.\n");
    5843             : 
    5844             : 
    5845           1 :         printf("finished delete test\n");
    5846             : 
    5847           1 :         correct = true;
    5848             : 
    5849           1 :   fail:
    5850             :         /* FIXME: This will crash if we aborted before cli2 got
    5851             :          * intialized, because these functions don't handle
    5852             :          * uninitialized connections. */
    5853             : 
    5854           1 :         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
    5855           1 :         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
    5856           1 :         cli_setatr(cli1, fname, 0, 0);
    5857           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5858             : 
    5859           1 :         if (cli1 && !torture_close_connection(cli1)) {
    5860           0 :                 correct = False;
    5861             :         }
    5862           1 :         if (cli2 && !torture_close_connection(cli2)) {
    5863           0 :                 correct = False;
    5864             :         }
    5865           1 :         return correct;
    5866             : }
    5867             : 
    5868             : struct delete_stream_state {
    5869             :         bool closed;
    5870             : };
    5871             : 
    5872             : static void delete_stream_unlinked(struct tevent_req *subreq);
    5873             : static void delete_stream_closed(struct tevent_req *subreq);
    5874             : 
    5875           1 : static struct tevent_req *delete_stream_send(
    5876             :         TALLOC_CTX *mem_ctx,
    5877             :         struct tevent_context *ev,
    5878             :         struct cli_state *cli,
    5879             :         const char *base_fname,
    5880             :         uint16_t stream_fnum)
    5881             : {
    5882           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    5883           1 :         struct delete_stream_state *state = NULL;
    5884             : 
    5885           1 :         req = tevent_req_create(
    5886             :                 mem_ctx, &state, struct delete_stream_state);
    5887           1 :         if (req == NULL) {
    5888           0 :                 return NULL;
    5889             :         }
    5890             : 
    5891           1 :         subreq = cli_unlink_send(
    5892             :                 state,
    5893             :                 ev,
    5894             :                 cli,
    5895             :                 base_fname,
    5896             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5897           1 :         if (tevent_req_nomem(subreq, req)) {
    5898           0 :                 return tevent_req_post(req, ev);
    5899             :         }
    5900           1 :         tevent_req_set_callback(subreq, delete_stream_unlinked, req);
    5901             : 
    5902           1 :         subreq = cli_close_send(state, ev, cli, stream_fnum);
    5903           1 :         if (tevent_req_nomem(subreq, req)) {
    5904           0 :                 return tevent_req_post(req, ev);
    5905             :         }
    5906           1 :         tevent_req_set_callback(subreq, delete_stream_closed, req);
    5907             : 
    5908           1 :         return req;
    5909             : }
    5910             : 
    5911           1 : static void delete_stream_unlinked(struct tevent_req *subreq)
    5912             : {
    5913           1 :         struct tevent_req *req = tevent_req_callback_data(
    5914             :                 subreq, struct tevent_req);
    5915           1 :         struct delete_stream_state *state = tevent_req_data(
    5916             :                 req, struct delete_stream_state);
    5917             :         NTSTATUS status;
    5918             : 
    5919           1 :         status = cli_unlink_recv(subreq);
    5920           1 :         TALLOC_FREE(subreq);
    5921           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    5922           0 :                 printf("cli_unlink returned %s\n",
    5923             :                        nt_errstr(status));
    5924           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5925           0 :                 return;
    5926             :         }
    5927           1 :         if (!state->closed) {
    5928             :                 /* close reply should have come in first */
    5929           0 :                 printf("Not closed\n");
    5930           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5931           0 :                 return;
    5932             :         }
    5933           1 :         tevent_req_done(req);
    5934             : }
    5935             : 
    5936           1 : static void delete_stream_closed(struct tevent_req *subreq)
    5937             : {
    5938           1 :         struct tevent_req *req = tevent_req_callback_data(
    5939             :                 subreq, struct tevent_req);
    5940           1 :         struct delete_stream_state *state = tevent_req_data(
    5941             :                 req, struct delete_stream_state);
    5942             :         NTSTATUS status;
    5943             : 
    5944           1 :         status = cli_close_recv(subreq);
    5945           1 :         TALLOC_FREE(subreq);
    5946           1 :         if (tevent_req_nterror(req, status)) {
    5947           0 :                 return;
    5948             :         }
    5949             :         /* also waiting for the unlink to come back */
    5950           1 :         state->closed = true;
    5951             : }
    5952             : 
    5953           1 : static NTSTATUS delete_stream_recv(struct tevent_req *req)
    5954             : {
    5955           1 :         return tevent_req_simple_recv_ntstatus(req);
    5956             : }
    5957             : 
    5958           1 : static bool run_delete_stream(int dummy)
    5959             : {
    5960           1 :         struct tevent_context *ev = NULL;
    5961           1 :         struct tevent_req *req = NULL;
    5962           1 :         struct cli_state *cli = NULL;
    5963           1 :         const char fname[] = "delete_stream";
    5964           1 :         const char fname_stream[] = "delete_stream:Zone.Identifier:$DATA";
    5965             :         uint16_t fnum1, fnum2;
    5966             :         NTSTATUS status;
    5967             :         bool ok;
    5968             : 
    5969           1 :         printf("Starting stream delete test\n");
    5970             : 
    5971           1 :         ok = torture_open_connection(&cli, 0);
    5972           1 :         if (!ok) {
    5973           0 :                 return false;
    5974             :         }
    5975             : 
    5976           1 :         cli_setatr(cli, fname, 0, 0);
    5977           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5978             : 
    5979             :         /* Create the file. */
    5980           1 :         status = cli_ntcreate(
    5981             :                 cli,
    5982             :                 fname,
    5983             :                 0,
    5984             :                 READ_CONTROL_ACCESS,
    5985             :                 0,
    5986             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5987             :                 FILE_CREATE,
    5988             :                 0x0,
    5989             :                 0x0,
    5990             :                 &fnum1,
    5991             :                 NULL);
    5992           1 :         if (!NT_STATUS_IS_OK(status)) {
    5993           0 :                 d_fprintf(stderr,
    5994             :                           "cli_ntcreate of %s failed (%s)\n",
    5995             :                           fname,
    5996             :                           nt_errstr(status));
    5997           0 :                 return false;
    5998             :         }
    5999           1 :         status = cli_close(cli, fnum1);
    6000           1 :         if (!NT_STATUS_IS_OK(status)) {
    6001           0 :                 d_fprintf(stderr,
    6002             :                           "cli_close of %s failed (%s)\n",
    6003             :                           fname,
    6004             :                           nt_errstr(status));
    6005           0 :                 return false;
    6006             :         }
    6007             : 
    6008             :         /* Now create the stream. */
    6009           1 :         status = cli_ntcreate(
    6010             :                 cli,
    6011             :                 fname_stream,
    6012             :                 0,
    6013             :                 FILE_WRITE_DATA,
    6014             :                 0,
    6015             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6016             :                 FILE_CREATE,
    6017             :                 0x0,
    6018             :                 0x0,
    6019             :                 &fnum1,
    6020             :                 NULL);
    6021             : 
    6022           1 :         if (!NT_STATUS_IS_OK(status)) {
    6023           0 :                 d_fprintf(stderr,
    6024             :                           "cli_ntcreate of %s failed (%s)\n",
    6025             :                           fname_stream,
    6026             :                           nt_errstr(status));
    6027           0 :                 return false;
    6028             :         }
    6029             : 
    6030             :         /* open it a second time */
    6031             : 
    6032           1 :         status = cli_ntcreate(
    6033             :                 cli,
    6034             :                 fname_stream,
    6035             :                 0,
    6036             :                 FILE_WRITE_DATA,
    6037             :                 0,
    6038             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6039             :                 FILE_OPEN,
    6040             :                 0x0,
    6041             :                 0x0,
    6042             :                 &fnum2,
    6043             :                 NULL);
    6044             : 
    6045           1 :         if (!NT_STATUS_IS_OK(status)) {
    6046           0 :                 d_fprintf(stderr,
    6047             :                           "2nd cli_ntcreate of %s failed (%s)\n",
    6048             :                           fname_stream,
    6049             :                           nt_errstr(status));
    6050           0 :                 return false;
    6051             :         }
    6052             : 
    6053           1 :         ev = samba_tevent_context_init(talloc_tos());
    6054           1 :         if (ev == NULL) {
    6055           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    6056           0 :                 return false;
    6057             :         }
    6058             : 
    6059           1 :         req = delete_stream_send(ev, ev, cli, fname, fnum1);
    6060           1 :         if (req == NULL) {
    6061           0 :                 d_fprintf(stderr, "delete_stream_send failed\n");
    6062           0 :                 return false;
    6063             :         }
    6064             : 
    6065           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    6066           1 :         if (!ok) {
    6067           0 :                 d_fprintf(stderr,
    6068             :                           "tevent_req_poll_ntstatus failed: %s\n",
    6069             :                           nt_errstr(status));
    6070           0 :                 return false;
    6071             :         }
    6072             : 
    6073           1 :         status = delete_stream_recv(req);
    6074           1 :         TALLOC_FREE(req);
    6075           1 :         if (!NT_STATUS_IS_OK(status)) {
    6076           0 :                 d_fprintf(stderr,
    6077             :                           "delete_stream failed: %s\n",
    6078             :                           nt_errstr(status));
    6079           0 :                 return false;
    6080             :         }
    6081             : 
    6082           1 :         status = cli_close(cli, fnum2);
    6083           1 :         if (!NT_STATUS_IS_OK(status)) {
    6084           0 :                 d_fprintf(stderr,
    6085             :                           "close failed: %s\n",
    6086             :                           nt_errstr(status));
    6087           0 :                 return false;
    6088             :         }
    6089             : 
    6090           1 :         status = cli_unlink(
    6091             :                 cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6092           1 :         if (!NT_STATUS_IS_OK(status)) {
    6093           0 :                 d_fprintf(stderr,
    6094             :                           "unlink failed: %s\n",
    6095             :                           nt_errstr(status));
    6096           0 :                 return false;
    6097             :         }
    6098             : 
    6099           1 :         return true;
    6100             : }
    6101             : 
    6102             : /*
    6103             :   Exercise delete on close semantics - use on the PRINT1 share in torture
    6104             :   testing.
    6105             :  */
    6106           0 : static bool run_delete_print_test(int dummy)
    6107             : {
    6108           0 :         struct cli_state *cli1 = NULL;
    6109           0 :         const char *fname = "print_delete.file";
    6110           0 :         uint16_t fnum1 = (uint16_t)-1;
    6111           0 :         bool correct = false;
    6112           0 :         const char *buf = "print file data\n";
    6113             :         NTSTATUS status;
    6114             : 
    6115           0 :         printf("starting print delete test\n");
    6116             : 
    6117           0 :         if (!torture_open_connection(&cli1, 0)) {
    6118           0 :                 return false;
    6119             :         }
    6120             : 
    6121           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    6122             : 
    6123           0 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    6124             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    6125             :                               0, 0, &fnum1, NULL);
    6126           0 :         if (!NT_STATUS_IS_OK(status)) {
    6127           0 :                 printf("open of %s failed (%s)\n",
    6128             :                         fname,
    6129             :                         nt_errstr(status));
    6130           0 :                 goto fail;
    6131             :         }
    6132             : 
    6133           0 :         status = cli_writeall(cli1,
    6134             :                         fnum1,
    6135             :                         0,
    6136             :                         (const uint8_t *)buf,
    6137             :                         0, /* offset */
    6138             :                         strlen(buf), /* size */
    6139             :                         NULL);
    6140           0 :         if (!NT_STATUS_IS_OK(status)) {
    6141           0 :                 printf("writing print file data failed (%s)\n",
    6142             :                         nt_errstr(status));
    6143           0 :                 goto fail;
    6144             :         }
    6145             : 
    6146           0 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    6147           0 :         if (!NT_STATUS_IS_OK(status)) {
    6148           0 :                 printf("setting delete_on_close failed (%s)\n",
    6149             :                         nt_errstr(status));
    6150           0 :                 goto fail;
    6151             :         }
    6152             : 
    6153           0 :         status = cli_close(cli1, fnum1);
    6154           0 :         if (!NT_STATUS_IS_OK(status)) {
    6155           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    6156           0 :                 goto fail;
    6157             :         }
    6158             : 
    6159           0 :         printf("finished print delete test\n");
    6160             : 
    6161           0 :         correct = true;
    6162             : 
    6163           0 :   fail:
    6164             : 
    6165           0 :         if (fnum1 != (uint16_t)-1) {
    6166           0 :                 cli_close(cli1, fnum1);
    6167             :         }
    6168             : 
    6169           0 :         if (cli1 && !torture_close_connection(cli1)) {
    6170           0 :                 correct = false;
    6171             :         }
    6172           0 :         return correct;
    6173             : }
    6174             : 
    6175           0 : static bool run_deletetest_ln(int dummy)
    6176             : {
    6177             :         struct cli_state *cli;
    6178           0 :         const char *fname = "\\delete1";
    6179           0 :         const char *fname_ln = "\\delete1_ln";
    6180             :         uint16_t fnum;
    6181             :         uint16_t fnum1;
    6182             :         NTSTATUS status;
    6183           0 :         bool correct = true;
    6184             :         time_t t;
    6185             : 
    6186           0 :         printf("starting deletetest-ln\n");
    6187             : 
    6188           0 :         if (!torture_open_connection(&cli, 0)) {
    6189           0 :                 return false;
    6190             :         }
    6191             : 
    6192           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6193           0 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6194             : 
    6195           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6196             : 
    6197             :         /* Create the file. */
    6198           0 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6199           0 :         if (!NT_STATUS_IS_OK(status)) {
    6200           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    6201           0 :                 return false;
    6202             :         }
    6203             : 
    6204           0 :         status = cli_close(cli, fnum);
    6205           0 :         if (!NT_STATUS_IS_OK(status)) {
    6206           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    6207           0 :                 return false;
    6208             :         }
    6209             : 
    6210             :         /* Now create a hardlink. */
    6211           0 :         status = cli_hardlink(cli, fname, fname_ln);
    6212           0 :         if (!NT_STATUS_IS_OK(status)) {
    6213           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    6214           0 :                 return false;
    6215             :         }
    6216             : 
    6217             :         /* Open the original file. */
    6218           0 :         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
    6219             :                         FILE_ATTRIBUTE_NORMAL,
    6220             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6221             :                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
    6222           0 :         if (!NT_STATUS_IS_OK(status)) {
    6223           0 :                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
    6224           0 :                 return false;
    6225             :         }
    6226             : 
    6227             :         /* Unlink the hard link path. */
    6228           0 :         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
    6229             :                         FILE_ATTRIBUTE_NORMAL,
    6230             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6231             :                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
    6232           0 :         if (!NT_STATUS_IS_OK(status)) {
    6233           0 :                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
    6234           0 :                 return false;
    6235             :         }
    6236           0 :         status = cli_nt_delete_on_close(cli, fnum1, true);
    6237           0 :         if (!NT_STATUS_IS_OK(status)) {
    6238           0 :                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
    6239             :                         __location__, fname_ln, nt_errstr(status));
    6240           0 :                 return false;
    6241             :         }
    6242             : 
    6243           0 :         status = cli_close(cli, fnum1);
    6244           0 :         if (!NT_STATUS_IS_OK(status)) {
    6245           0 :                 printf("close %s failed (%s)\n",
    6246             :                         fname_ln, nt_errstr(status));
    6247           0 :                 return false;
    6248             :         }
    6249             : 
    6250           0 :         status = cli_close(cli, fnum);
    6251           0 :         if (!NT_STATUS_IS_OK(status)) {
    6252           0 :                 printf("close %s failed (%s)\n",
    6253             :                         fname, nt_errstr(status));
    6254           0 :                 return false;
    6255             :         }
    6256             : 
    6257             :         /* Ensure the original file is still there. */
    6258           0 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    6259           0 :         if (!NT_STATUS_IS_OK(status)) {
    6260           0 :                 printf("%s getatr on file %s failed (%s)\n",
    6261             :                         __location__,
    6262             :                         fname,
    6263             :                         nt_errstr(status));
    6264           0 :                 correct = False;
    6265             :         }
    6266             : 
    6267             :         /* Ensure the link path is gone. */
    6268           0 :         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
    6269           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    6270           0 :                 printf("%s, getatr for file %s returned wrong error code %s "
    6271             :                         "- should have been deleted\n",
    6272             :                         __location__,
    6273             :                         fname_ln, nt_errstr(status));
    6274           0 :                 correct = False;
    6275             :         }
    6276             : 
    6277           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6278           0 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6279             : 
    6280           0 :         if (!torture_close_connection(cli)) {
    6281           0 :                 correct = false;
    6282             :         }
    6283             : 
    6284           0 :         printf("finished deletetest-ln\n");
    6285             : 
    6286           0 :         return correct;
    6287             : }
    6288             : 
    6289             : /*
    6290             :   print out server properties
    6291             :  */
    6292           1 : static bool run_properties(int dummy)
    6293             : {
    6294             :         struct cli_state *cli;
    6295           1 :         bool correct = True;
    6296             : 
    6297           1 :         printf("starting properties test\n");
    6298             : 
    6299           1 :         ZERO_STRUCT(cli);
    6300             : 
    6301           1 :         if (!torture_open_connection(&cli, 0)) {
    6302           0 :                 return False;
    6303             :         }
    6304             : 
    6305           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6306             : 
    6307           1 :         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
    6308             : 
    6309           1 :         if (!torture_close_connection(cli)) {
    6310           0 :                 correct = False;
    6311             :         }
    6312             : 
    6313           1 :         return correct;
    6314             : }
    6315             : 
    6316             : 
    6317             : 
    6318             : /* FIRST_DESIRED_ACCESS   0xf019f */
    6319             : #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
    6320             :                                FILE_READ_EA|                           /* 0xf */ \
    6321             :                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
    6322             :                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
    6323             :                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
    6324             :                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
    6325             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    6326             : #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6327             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6328             :                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
    6329             : 
    6330             : #if 0
    6331             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6332             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6333             :                                FILE_READ_DATA|\
    6334             :                                WRITE_OWNER_ACCESS                      /* */
    6335             : #endif
    6336             : 
    6337             : /*
    6338             :   Test ntcreate calls made by xcopy
    6339             :  */
    6340           1 : static bool run_xcopy(int dummy)
    6341             : {
    6342             :         static struct cli_state *cli1;
    6343           1 :         const char *fname = "\\test.txt";
    6344           1 :         bool correct = True;
    6345             :         uint16_t fnum1, fnum2;
    6346             :         NTSTATUS status;
    6347             : 
    6348           1 :         printf("starting xcopy test\n");
    6349             : 
    6350           1 :         if (!torture_open_connection(&cli1, 0)) {
    6351           0 :                 return False;
    6352             :         }
    6353             : 
    6354           1 :         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
    6355             :                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
    6356             :                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
    6357           1 :         if (!NT_STATUS_IS_OK(status)) {
    6358           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6359           0 :                 return False;
    6360             :         }
    6361             : 
    6362           1 :         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
    6363             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6364             :                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
    6365           1 :         if (!NT_STATUS_IS_OK(status)) {
    6366           0 :                 printf("second open failed - %s\n", nt_errstr(status));
    6367           0 :                 return False;
    6368             :         }
    6369             : 
    6370           1 :         if (!torture_close_connection(cli1)) {
    6371           0 :                 correct = False;
    6372             :         }
    6373             : 
    6374           1 :         return correct;
    6375             : }
    6376             : 
    6377             : /*
    6378             :   Test rename on files open with share delete and no share delete.
    6379             :  */
    6380           1 : static bool run_rename(int dummy)
    6381             : {
    6382             :         static struct cli_state *cli1;
    6383           1 :         const char *fname = "\\test.txt";
    6384           1 :         const char *fname1 = "\\test1.txt";
    6385           1 :         bool correct = True;
    6386             :         uint16_t fnum1;
    6387             :         uint32_t attr;
    6388             :         NTSTATUS status;
    6389             : 
    6390           1 :         printf("starting rename test\n");
    6391             : 
    6392           1 :         if (!torture_open_connection(&cli1, 0)) {
    6393           0 :                 return False;
    6394             :         }
    6395             : 
    6396           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6397           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6398             : 
    6399           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6400             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    6401             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6402           1 :         if (!NT_STATUS_IS_OK(status)) {
    6403           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6404           0 :                 return False;
    6405             :         }
    6406             : 
    6407           1 :         status = cli_rename(cli1, fname, fname1, false);
    6408           1 :         if (!NT_STATUS_IS_OK(status)) {
    6409           1 :                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
    6410             :         } else {
    6411           0 :                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
    6412           0 :                 correct = False;
    6413             :         }
    6414             : 
    6415           1 :         status = cli_close(cli1, fnum1);
    6416           1 :         if (!NT_STATUS_IS_OK(status)) {
    6417           0 :                 printf("close - 1 failed (%s)\n", nt_errstr(status));
    6418           0 :                 return False;
    6419             :         }
    6420             : 
    6421           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6422           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6423           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
    6424             : #if 0
    6425             :                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
    6426             : #else
    6427             :                               FILE_SHARE_DELETE|FILE_SHARE_READ,
    6428             : #endif
    6429             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6430           1 :         if (!NT_STATUS_IS_OK(status)) {
    6431           0 :                 printf("Second open failed - %s\n", nt_errstr(status));
    6432           0 :                 return False;
    6433             :         }
    6434             : 
    6435           1 :         status = cli_rename(cli1, fname, fname1, false);
    6436           1 :         if (!NT_STATUS_IS_OK(status)) {
    6437           0 :                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
    6438           0 :                 correct = False;
    6439             :         } else {
    6440           1 :                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
    6441             :         }
    6442             : 
    6443           1 :         status = cli_close(cli1, fnum1);
    6444           1 :         if (!NT_STATUS_IS_OK(status)) {
    6445           0 :                 printf("close - 2 failed (%s)\n", nt_errstr(status));
    6446           0 :                 return False;
    6447             :         }
    6448             : 
    6449           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6450           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6451             : 
    6452           1 :         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
    6453             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    6454             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6455           1 :         if (!NT_STATUS_IS_OK(status)) {
    6456           0 :                 printf("Third open failed - %s\n", nt_errstr(status));
    6457           0 :                 return False;
    6458             :         }
    6459             : 
    6460             : 
    6461           1 :         status = cli_rename(cli1, fname, fname1, false);
    6462           1 :         if (!NT_STATUS_IS_OK(status)) {
    6463           0 :                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
    6464           0 :                 correct = False;
    6465             :         } else {
    6466           1 :                 printf("Third rename succeeded (SHARE_NONE)\n");
    6467             :         }
    6468             : 
    6469           1 :         status = cli_close(cli1, fnum1);
    6470           1 :         if (!NT_STATUS_IS_OK(status)) {
    6471           0 :                 printf("close - 3 failed (%s)\n", nt_errstr(status));
    6472           0 :                 return False;
    6473             :         }
    6474             : 
    6475           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6476           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6477             : 
    6478             :         /*----*/
    6479             : 
    6480           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6481             :                               FILE_ATTRIBUTE_NORMAL,
    6482             :                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    6483             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6484           1 :         if (!NT_STATUS_IS_OK(status)) {
    6485           0 :                 printf("Fourth open failed - %s\n", nt_errstr(status));
    6486           0 :                 return False;
    6487             :         }
    6488             : 
    6489           1 :         status = cli_rename(cli1, fname, fname1, false);
    6490           1 :         if (!NT_STATUS_IS_OK(status)) {
    6491           1 :                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
    6492             :         } else {
    6493           0 :                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
    6494           0 :                 correct = False;
    6495             :         }
    6496             : 
    6497           1 :         status = cli_close(cli1, fnum1);
    6498           1 :         if (!NT_STATUS_IS_OK(status)) {
    6499           0 :                 printf("close - 4 failed (%s)\n", nt_errstr(status));
    6500           0 :                 return False;
    6501             :         }
    6502             : 
    6503           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6504           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6505             : 
    6506             :         /*--*/
    6507             : 
    6508           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6509             :                          FILE_ATTRIBUTE_NORMAL,
    6510             :                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    6511             :                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6512           1 :         if (!NT_STATUS_IS_OK(status)) {
    6513           0 :                 printf("Fifth open failed - %s\n", nt_errstr(status));
    6514           0 :                 return False;
    6515             :         }
    6516             : 
    6517           1 :         status = cli_rename(cli1, fname, fname1, false);
    6518           1 :         if (!NT_STATUS_IS_OK(status)) {
    6519           0 :                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
    6520           0 :                 correct = False;
    6521             :         } else {
    6522           1 :                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
    6523             :         }
    6524             : 
    6525             :         /*--*/
    6526           1 :         status = cli_close(cli1, fnum1);
    6527           1 :         if (!NT_STATUS_IS_OK(status)) {
    6528           0 :                 printf("close - 5 failed (%s)\n", nt_errstr(status));
    6529           0 :                 return False;
    6530             :         }
    6531             : 
    6532             :         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
    6533           1 :         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
    6534           1 :         if (!NT_STATUS_IS_OK(status)) {
    6535           0 :                 printf("getatr on file %s failed - %s ! \n",
    6536             :                         fname1, nt_errstr(status));
    6537           0 :                 correct = False;
    6538             :         } else {
    6539           1 :                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
    6540           0 :                         printf("Renamed file %s has wrong attr 0x%x "
    6541             :                                 "(should be 0x%x)\n",
    6542             :                                 fname1,
    6543             :                                 attr,
    6544             :                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
    6545           0 :                         correct = False;
    6546             :                 } else {
    6547           1 :                         printf("Renamed file %s has archive bit set\n", fname1);
    6548             :                 }
    6549             :         }
    6550             : 
    6551           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6552           1 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6553             : 
    6554           1 :         if (!torture_close_connection(cli1)) {
    6555           0 :                 correct = False;
    6556             :         }
    6557             : 
    6558           1 :         return correct;
    6559             : }
    6560             : 
    6561             : /*
    6562             :   Test rename into a directory with an ACL denying it.
    6563             :  */
    6564           0 : static bool run_rename_access(int dummy)
    6565             : {
    6566             :         static struct cli_state *cli = NULL;
    6567             :         static struct cli_state *posix_cli = NULL;
    6568           0 :         const char *src = "test.txt";
    6569           0 :         const char *dname = "dir";
    6570           0 :         const char *dst = "dir\\test.txt";
    6571           0 :         const char *dsrc = "test.dir";
    6572           0 :         const char *ddst = "dir\\test.dir";
    6573           0 :         uint16_t fnum = (uint16_t)-1;
    6574           0 :         struct security_descriptor *sd = NULL;
    6575           0 :         struct security_descriptor *newsd = NULL;
    6576             :         NTSTATUS status;
    6577           0 :         TALLOC_CTX *frame = NULL;
    6578             : 
    6579           0 :         frame = talloc_stackframe();
    6580           0 :         printf("starting rename access test\n");
    6581             : 
    6582             :         /* Windows connection. */
    6583           0 :         if (!torture_open_connection(&cli, 0)) {
    6584           0 :                 goto fail;
    6585             :         }
    6586             : 
    6587           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6588             : 
    6589             :         /* Posix connection. */
    6590           0 :         if (!torture_open_connection(&posix_cli, 0)) {
    6591           0 :                 goto fail;
    6592             :         }
    6593             : 
    6594           0 :         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
    6595             : 
    6596           0 :         status = torture_setup_unix_extensions(posix_cli);
    6597           0 :         if (!NT_STATUS_IS_OK(status)) {
    6598           0 :                 goto fail;
    6599             :         }
    6600             : 
    6601             :         /* Start with a clean slate. */
    6602           0 :         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6603           0 :         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6604           0 :         cli_rmdir(cli, dsrc);
    6605           0 :         cli_rmdir(cli, ddst);
    6606           0 :         cli_rmdir(cli, dname);
    6607             : 
    6608             :         /*
    6609             :          * Setup the destination directory with a DENY ACE to
    6610             :          * prevent new files within it.
    6611             :          */
    6612           0 :         status = cli_ntcreate(cli,
    6613             :                                 dname,
    6614             :                                 0,
    6615             :                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
    6616             :                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
    6617             :                                         WRITE_OWNER_ACCESS,
    6618             :                                 FILE_ATTRIBUTE_DIRECTORY,
    6619             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6620             :                                 FILE_CREATE,
    6621             :                                 FILE_DIRECTORY_FILE,
    6622             :                                 0,
    6623             :                                 &fnum,
    6624             :                                 NULL);
    6625           0 :         if (!NT_STATUS_IS_OK(status)) {
    6626           0 :                 printf("Create of %s - %s\n", dname, nt_errstr(status));
    6627           0 :                 goto fail;
    6628             :         }
    6629             : 
    6630           0 :         status = cli_query_secdesc(cli,
    6631             :                                 fnum,
    6632             :                                 frame,
    6633             :                                 &sd);
    6634           0 :         if (!NT_STATUS_IS_OK(status)) {
    6635           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6636             :                         dname, nt_errstr(status));
    6637           0 :                 goto fail;
    6638             :         }
    6639             : 
    6640           0 :         newsd = security_descriptor_dacl_create(frame,
    6641             :                                         0,
    6642             :                                         NULL,
    6643             :                                         NULL,
    6644             :                                         SID_WORLD,
    6645             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6646             :                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
    6647             :                                         0,
    6648             :                                         NULL);
    6649           0 :         if (newsd == NULL) {
    6650           0 :                 goto fail;
    6651             :         }
    6652           0 :         sd->dacl = security_acl_concatenate(frame,
    6653           0 :                                         newsd->dacl,
    6654           0 :                                         sd->dacl);
    6655           0 :         if (sd->dacl == NULL) {
    6656           0 :                 goto fail;
    6657             :         }
    6658           0 :         status = cli_set_secdesc(cli, fnum, sd);
    6659           0 :         if (!NT_STATUS_IS_OK(status)) {
    6660           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6661             :                         dname, nt_errstr(status));
    6662           0 :                 goto fail;
    6663             :         }
    6664           0 :         status = cli_close(cli, fnum);
    6665           0 :         if (!NT_STATUS_IS_OK(status)) {
    6666           0 :                 printf("close failed for %s (%s)\n",
    6667             :                         dname, nt_errstr(status));
    6668           0 :                 goto fail;
    6669             :         }
    6670             :         /* Now go around the back and chmod to 777 via POSIX. */
    6671           0 :         status = cli_posix_chmod(posix_cli, dname, 0777);
    6672           0 :         if (!NT_STATUS_IS_OK(status)) {
    6673           0 :                 printf("cli_posix_chmod failed for %s (%s)\n",
    6674             :                         dname, nt_errstr(status));
    6675           0 :                 goto fail;
    6676             :         }
    6677             : 
    6678             :         /* Check we can't create a file within dname via Windows. */
    6679           0 :         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6680           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6681           0 :                 cli_close(posix_cli, fnum);
    6682           0 :                 printf("Create of %s should be ACCESS denied, was %s\n",
    6683             :                         dst, nt_errstr(status));
    6684           0 :                 goto fail;
    6685             :         }
    6686             : 
    6687             :         /* Make the sample file/directory. */
    6688           0 :         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6689           0 :         if (!NT_STATUS_IS_OK(status)) {
    6690           0 :                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
    6691           0 :                 goto fail;
    6692             :         }
    6693           0 :         status = cli_close(cli, fnum);
    6694           0 :         if (!NT_STATUS_IS_OK(status)) {
    6695           0 :                 printf("cli_close failed (%s)\n", nt_errstr(status));
    6696           0 :                 goto fail;
    6697             :         }
    6698             : 
    6699           0 :         status = cli_mkdir(cli, dsrc);
    6700           0 :         if (!NT_STATUS_IS_OK(status)) {
    6701           0 :                 printf("cli_mkdir of %s failed (%s)\n",
    6702             :                         dsrc, nt_errstr(status));
    6703           0 :                 goto fail;
    6704             :         }
    6705             : 
    6706             :         /*
    6707             :          * OK - renames of the new file and directory into the
    6708             :          * dst directory should fail.
    6709             :          */
    6710             : 
    6711           0 :         status = cli_rename(cli, src, dst, false);
    6712           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6713           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6714             :                         src, dst, nt_errstr(status));
    6715           0 :                 goto fail;
    6716             :         }
    6717           0 :         status = cli_rename(cli, dsrc, ddst, false);
    6718           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6719           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6720             :                         src, dst, nt_errstr(status));
    6721           0 :                 goto fail;
    6722             :         }
    6723             : 
    6724           0 :         TALLOC_FREE(frame);
    6725           0 :         return true;
    6726             : 
    6727           0 :   fail:
    6728             : 
    6729           0 :         if (posix_cli) {
    6730           0 :                 torture_close_connection(posix_cli);
    6731             :         }
    6732             : 
    6733           0 :         if (cli) {
    6734           0 :                 if (fnum != (uint16_t)-1) {
    6735           0 :                         cli_close(cli, fnum);
    6736             :                 }
    6737           0 :                 cli_unlink(cli, src,
    6738             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6739           0 :                 cli_unlink(cli, dst,
    6740             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6741           0 :                 cli_rmdir(cli, dsrc);
    6742           0 :                 cli_rmdir(cli, ddst);
    6743           0 :                 cli_rmdir(cli, dname);
    6744             : 
    6745           0 :                 torture_close_connection(cli);
    6746             :         }
    6747             : 
    6748           0 :         TALLOC_FREE(frame);
    6749           0 :         return false;
    6750             : }
    6751             : 
    6752             : /*
    6753             :   Test owner rights ACE.
    6754             :  */
    6755           0 : static bool run_owner_rights(int dummy)
    6756             : {
    6757             :         static struct cli_state *cli = NULL;
    6758           0 :         const char *fname = "owner_rights.txt";
    6759           0 :         uint16_t fnum = (uint16_t)-1;
    6760           0 :         struct security_descriptor *sd = NULL;
    6761           0 :         struct security_descriptor *newsd = NULL;
    6762             :         NTSTATUS status;
    6763           0 :         TALLOC_CTX *frame = NULL;
    6764             : 
    6765           0 :         frame = talloc_stackframe();
    6766           0 :         printf("starting owner rights test\n");
    6767             : 
    6768             :         /* Windows connection. */
    6769           0 :         if (!torture_open_connection(&cli, 0)) {
    6770           0 :                 goto fail;
    6771             :         }
    6772             : 
    6773           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6774             : 
    6775             :         /* Start with a clean slate. */
    6776           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6777             : 
    6778             :         /* Create the test file. */
    6779             :         /* Now try and open for read and write-dac. */
    6780           0 :         status = cli_ntcreate(cli,
    6781             :                                 fname,
    6782             :                                 0,
    6783             :                                 GENERIC_ALL_ACCESS,
    6784             :                                 FILE_ATTRIBUTE_NORMAL,
    6785             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6786             :                                         FILE_SHARE_DELETE,
    6787             :                                 FILE_CREATE,
    6788             :                                 0,
    6789             :                                 0,
    6790             :                                 &fnum,
    6791             :                                 NULL);
    6792           0 :         if (!NT_STATUS_IS_OK(status)) {
    6793           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6794           0 :                 goto fail;
    6795             :         }
    6796             : 
    6797             :         /* Get the original SD. */
    6798           0 :         status = cli_query_secdesc(cli,
    6799             :                                 fnum,
    6800             :                                 frame,
    6801             :                                 &sd);
    6802           0 :         if (!NT_STATUS_IS_OK(status)) {
    6803           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6804             :                         fname, nt_errstr(status));
    6805           0 :                 goto fail;
    6806             :         }
    6807             : 
    6808             :         /*
    6809             :          * Add an "owner-rights" ACE denying WRITE_DATA,
    6810             :          * and an "owner-rights" ACE allowing READ_DATA.
    6811             :          */
    6812             : 
    6813           0 :         newsd = security_descriptor_dacl_create(frame,
    6814             :                                         0,
    6815             :                                         NULL,
    6816             :                                         NULL,
    6817             :                                         SID_OWNER_RIGHTS,
    6818             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6819             :                                         FILE_WRITE_DATA,
    6820             :                                         0,
    6821             :                                         SID_OWNER_RIGHTS,
    6822             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6823             :                                         FILE_READ_DATA,
    6824             :                                         0,
    6825             :                                         NULL);
    6826           0 :         if (newsd == NULL) {
    6827           0 :                 goto fail;
    6828             :         }
    6829           0 :         sd->dacl = security_acl_concatenate(frame,
    6830           0 :                                         newsd->dacl,
    6831           0 :                                         sd->dacl);
    6832           0 :         if (sd->dacl == NULL) {
    6833           0 :                 goto fail;
    6834             :         }
    6835           0 :         status = cli_set_secdesc(cli, fnum, sd);
    6836           0 :         if (!NT_STATUS_IS_OK(status)) {
    6837           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6838             :                         fname, nt_errstr(status));
    6839           0 :                 goto fail;
    6840             :         }
    6841           0 :         status = cli_close(cli, fnum);
    6842           0 :         if (!NT_STATUS_IS_OK(status)) {
    6843           0 :                 printf("close failed for %s (%s)\n",
    6844             :                         fname, nt_errstr(status));
    6845           0 :                 goto fail;
    6846             :         }
    6847           0 :         fnum = (uint16_t)-1;
    6848             : 
    6849             :         /* Try and open for FILE_WRITE_DATA */
    6850           0 :         status = cli_ntcreate(cli,
    6851             :                                 fname,
    6852             :                                 0,
    6853             :                                 FILE_WRITE_DATA,
    6854             :                                 FILE_ATTRIBUTE_NORMAL,
    6855             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6856             :                                         FILE_SHARE_DELETE,
    6857             :                                 FILE_OPEN,
    6858             :                                 0,
    6859             :                                 0,
    6860             :                                 &fnum,
    6861             :                                 NULL);
    6862           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6863           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6864           0 :                 goto fail;
    6865             :         }
    6866             : 
    6867             :         /* Now try and open for FILE_READ_DATA */
    6868           0 :         status = cli_ntcreate(cli,
    6869             :                                 fname,
    6870             :                                 0,
    6871             :                                 FILE_READ_DATA,
    6872             :                                 FILE_ATTRIBUTE_NORMAL,
    6873             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6874             :                                         FILE_SHARE_DELETE,
    6875             :                                 FILE_OPEN,
    6876             :                                 0,
    6877             :                                 0,
    6878             :                                 &fnum,
    6879             :                                 NULL);
    6880           0 :         if (!NT_STATUS_IS_OK(status)) {
    6881           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6882           0 :                 goto fail;
    6883             :         }
    6884             : 
    6885           0 :         status = cli_close(cli, fnum);
    6886           0 :         if (!NT_STATUS_IS_OK(status)) {
    6887           0 :                 printf("close failed for %s (%s)\n",
    6888             :                         fname, nt_errstr(status));
    6889           0 :                 goto fail;
    6890             :         }
    6891             : 
    6892             :         /* Restore clean slate. */
    6893           0 :         TALLOC_FREE(sd);
    6894           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6895             : 
    6896             :         /* Create the test file. */
    6897           0 :         status = cli_ntcreate(cli,
    6898             :                                 fname,
    6899             :                                 0,
    6900             :                                 GENERIC_ALL_ACCESS,
    6901             :                                 FILE_ATTRIBUTE_NORMAL,
    6902             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6903             :                                         FILE_SHARE_DELETE,
    6904             :                                 FILE_CREATE,
    6905             :                                 0,
    6906             :                                 0,
    6907             :                                 &fnum,
    6908             :                                 NULL);
    6909           0 :         if (!NT_STATUS_IS_OK(status)) {
    6910           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6911           0 :                 goto fail;
    6912             :         }
    6913             : 
    6914             :         /* Get the original SD. */
    6915           0 :         status = cli_query_secdesc(cli,
    6916             :                                 fnum,
    6917             :                                 frame,
    6918             :                                 &sd);
    6919           0 :         if (!NT_STATUS_IS_OK(status)) {
    6920           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6921             :                         fname, nt_errstr(status));
    6922           0 :                 goto fail;
    6923             :         }
    6924             : 
    6925             :         /*
    6926             :          * Add an "owner-rights ACE denying WRITE_DATA,
    6927             :          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
    6928             :          */
    6929             : 
    6930           0 :         newsd = security_descriptor_dacl_create(frame,
    6931             :                                         0,
    6932             :                                         NULL,
    6933             :                                         NULL,
    6934             :                                         SID_OWNER_RIGHTS,
    6935             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6936             :                                         FILE_WRITE_DATA,
    6937             :                                         0,
    6938             :                                         SID_OWNER_RIGHTS,
    6939             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6940             :                                         FILE_READ_DATA|FILE_WRITE_DATA,
    6941             :                                         0,
    6942             :                                         NULL);
    6943           0 :         if (newsd == NULL) {
    6944           0 :                 goto fail;
    6945             :         }
    6946           0 :         sd->dacl = security_acl_concatenate(frame,
    6947           0 :                                         newsd->dacl,
    6948           0 :                                         sd->dacl);
    6949           0 :         if (sd->dacl == NULL) {
    6950           0 :                 goto fail;
    6951             :         }
    6952           0 :         status = cli_set_secdesc(cli, fnum, sd);
    6953           0 :         if (!NT_STATUS_IS_OK(status)) {
    6954           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6955             :                         fname, nt_errstr(status));
    6956           0 :                 goto fail;
    6957             :         }
    6958           0 :         status = cli_close(cli, fnum);
    6959           0 :         if (!NT_STATUS_IS_OK(status)) {
    6960           0 :                 printf("close failed for %s (%s)\n",
    6961             :                         fname, nt_errstr(status));
    6962           0 :                 goto fail;
    6963             :         }
    6964           0 :         fnum = (uint16_t)-1;
    6965             : 
    6966             :         /* Try and open for FILE_WRITE_DATA */
    6967           0 :         status = cli_ntcreate(cli,
    6968             :                                 fname,
    6969             :                                 0,
    6970             :                                 FILE_WRITE_DATA,
    6971             :                                 FILE_ATTRIBUTE_NORMAL,
    6972             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6973             :                                         FILE_SHARE_DELETE,
    6974             :                                 FILE_OPEN,
    6975             :                                 0,
    6976             :                                 0,
    6977             :                                 &fnum,
    6978             :                                 NULL);
    6979           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6980           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6981           0 :                 goto fail;
    6982             :         }
    6983             : 
    6984             :         /* Now try and open for FILE_READ_DATA */
    6985           0 :         status = cli_ntcreate(cli,
    6986             :                                 fname,
    6987             :                                 0,
    6988             :                                 FILE_READ_DATA,
    6989             :                                 FILE_ATTRIBUTE_NORMAL,
    6990             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6991             :                                         FILE_SHARE_DELETE,
    6992             :                                 FILE_OPEN,
    6993             :                                 0,
    6994             :                                 0,
    6995             :                                 &fnum,
    6996             :                                 NULL);
    6997           0 :         if (!NT_STATUS_IS_OK(status)) {
    6998           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6999           0 :                 goto fail;
    7000             :         }
    7001             : 
    7002           0 :         status = cli_close(cli, fnum);
    7003           0 :         if (!NT_STATUS_IS_OK(status)) {
    7004           0 :                 printf("close failed for %s (%s)\n",
    7005             :                         fname, nt_errstr(status));
    7006           0 :                 goto fail;
    7007             :         }
    7008             : 
    7009             :         /* Restore clean slate. */
    7010           0 :         TALLOC_FREE(sd);
    7011           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7012             : 
    7013             : 
    7014             :         /* Create the test file. */
    7015           0 :         status = cli_ntcreate(cli,
    7016             :                                 fname,
    7017             :                                 0,
    7018             :                                 GENERIC_ALL_ACCESS,
    7019             :                                 FILE_ATTRIBUTE_NORMAL,
    7020             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7021             :                                         FILE_SHARE_DELETE,
    7022             :                                 FILE_CREATE,
    7023             :                                 0,
    7024             :                                 0,
    7025             :                                 &fnum,
    7026             :                                 NULL);
    7027           0 :         if (!NT_STATUS_IS_OK(status)) {
    7028           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7029           0 :                 goto fail;
    7030             :         }
    7031             : 
    7032             :         /* Get the original SD. */
    7033           0 :         status = cli_query_secdesc(cli,
    7034             :                                 fnum,
    7035             :                                 frame,
    7036             :                                 &sd);
    7037           0 :         if (!NT_STATUS_IS_OK(status)) {
    7038           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    7039             :                         fname, nt_errstr(status));
    7040           0 :                 goto fail;
    7041             :         }
    7042             : 
    7043             :         /*
    7044             :          * Add an "authenticated users" ACE allowing READ_DATA,
    7045             :          * add an "owner-rights" denying READ_DATA,
    7046             :          * and an "authenticated users" ACE allowing WRITE_DATA.
    7047             :          */
    7048             : 
    7049           0 :         newsd = security_descriptor_dacl_create(frame,
    7050             :                                         0,
    7051             :                                         NULL,
    7052             :                                         NULL,
    7053             :                                         SID_NT_AUTHENTICATED_USERS,
    7054             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7055             :                                         FILE_READ_DATA,
    7056             :                                         0,
    7057             :                                         SID_OWNER_RIGHTS,
    7058             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7059             :                                         FILE_READ_DATA,
    7060             :                                         0,
    7061             :                                         SID_NT_AUTHENTICATED_USERS,
    7062             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7063             :                                         FILE_WRITE_DATA,
    7064             :                                         0,
    7065             :                                         NULL);
    7066           0 :         if (newsd == NULL) {
    7067           0 :                 printf("newsd == NULL\n");
    7068           0 :                 goto fail;
    7069             :         }
    7070           0 :         sd->dacl = security_acl_concatenate(frame,
    7071           0 :                                         newsd->dacl,
    7072           0 :                                         sd->dacl);
    7073           0 :         if (sd->dacl == NULL) {
    7074           0 :                 printf("sd->dacl == NULL\n");
    7075           0 :                 goto fail;
    7076             :         }
    7077           0 :         status = cli_set_secdesc(cli, fnum, sd);
    7078           0 :         if (!NT_STATUS_IS_OK(status)) {
    7079           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7080             :                         fname, nt_errstr(status));
    7081           0 :                 goto fail;
    7082             :         }
    7083           0 :         status = cli_close(cli, fnum);
    7084           0 :         if (!NT_STATUS_IS_OK(status)) {
    7085           0 :                 printf("close failed for %s (%s)\n",
    7086             :                         fname, nt_errstr(status));
    7087           0 :                 goto fail;
    7088             :         }
    7089           0 :         fnum = (uint16_t)-1;
    7090             : 
    7091             :         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
    7092           0 :         status = cli_ntcreate(cli,
    7093             :                                 fname,
    7094             :                                 0,
    7095             :                                 FILE_READ_DATA|FILE_WRITE_DATA,
    7096             :                                 FILE_ATTRIBUTE_NORMAL,
    7097             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7098             :                                         FILE_SHARE_DELETE,
    7099             :                                 FILE_OPEN,
    7100             :                                 0,
    7101             :                                 0,
    7102             :                                 &fnum,
    7103             :                                 NULL);
    7104           0 :         if (!NT_STATUS_IS_OK(status)) {
    7105           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7106           0 :                 goto fail;
    7107             :         }
    7108             : 
    7109           0 :         status = cli_close(cli, fnum);
    7110           0 :         if (!NT_STATUS_IS_OK(status)) {
    7111           0 :                 printf("close failed for %s (%s)\n",
    7112             :                         fname, nt_errstr(status));
    7113           0 :                 goto fail;
    7114             :         }
    7115             : 
    7116           0 :         cli_unlink(cli, fname,
    7117             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7118             : 
    7119           0 :         TALLOC_FREE(frame);
    7120           0 :         return true;
    7121             : 
    7122           0 :   fail:
    7123             : 
    7124           0 :         if (cli) {
    7125           0 :                 if (fnum != (uint16_t)-1) {
    7126           0 :                         cli_close(cli, fnum);
    7127             :                 }
    7128           0 :                 cli_unlink(cli, fname,
    7129             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7130           0 :                 torture_close_connection(cli);
    7131             :         }
    7132             : 
    7133           0 :         TALLOC_FREE(frame);
    7134           0 :         return false;
    7135             : }
    7136             : 
    7137             : /*
    7138             :  * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
    7139             :  * Note this test only works with a user with SeSecurityPrivilege set.
    7140             :  *
    7141             :  * NB. This is also tested in samba3.base.createx_access
    7142             :  * but this makes it very explicit what we're looking for.
    7143             :  */
    7144           0 : static bool run_smb1_system_security(int dummy)
    7145             : {
    7146             :         static struct cli_state *cli = NULL;
    7147           0 :         const char *fname = "system_security.txt";
    7148           0 :         uint16_t fnum = (uint16_t)-1;
    7149             :         NTSTATUS status;
    7150           0 :         TALLOC_CTX *frame = NULL;
    7151             : 
    7152           0 :         frame = talloc_stackframe();
    7153           0 :         printf("starting smb1 system security test\n");
    7154             : 
    7155             :         /* SMB1 connection - torture_open_connection() forces this. */
    7156           0 :         if (!torture_open_connection(&cli, 0)) {
    7157           0 :                 goto fail;
    7158             :         }
    7159             : 
    7160           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    7161             : 
    7162             :         /* Start with a clean slate. */
    7163           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7164             : 
    7165             :         /* Create the test file. */
    7166           0 :         status = cli_ntcreate(cli,
    7167             :                                 fname,
    7168             :                                 0,
    7169             :                                 GENERIC_ALL_ACCESS,
    7170             :                                 FILE_ATTRIBUTE_NORMAL,
    7171             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7172             :                                         FILE_SHARE_DELETE,
    7173             :                                 FILE_CREATE,
    7174             :                                 0,
    7175             :                                 0,
    7176             :                                 &fnum,
    7177             :                                 NULL);
    7178           0 :         if (!NT_STATUS_IS_OK(status)) {
    7179           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7180           0 :                 goto fail;
    7181             :         }
    7182             : 
    7183           0 :         status = cli_close(cli, fnum);
    7184             : 
    7185             :         /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
    7186             :         /*
    7187             :          * On SMB1 this succeeds - SMB2 it fails,
    7188             :          * see the SMB2-SACL test.
    7189             :          */
    7190           0 :         status = cli_ntcreate(cli,
    7191             :                                 fname,
    7192             :                                 0,
    7193             :                                 SEC_FLAG_SYSTEM_SECURITY,
    7194             :                                 FILE_ATTRIBUTE_NORMAL,
    7195             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7196             :                                         FILE_SHARE_DELETE,
    7197             :                                 FILE_OPEN,
    7198             :                                 0,
    7199             :                                 0,
    7200             :                                 &fnum,
    7201             :                                 NULL);
    7202           0 :         if (!NT_STATUS_IS_OK(status)) {
    7203           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7204           0 :                 goto fail;
    7205             :         }
    7206             : 
    7207           0 :         status = cli_close(cli, fnum);
    7208             : 
    7209           0 :         cli_unlink(cli, fname,
    7210             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7211             : 
    7212           0 :         torture_close_connection(cli);
    7213           0 :         TALLOC_FREE(frame);
    7214           0 :         return true;
    7215             : 
    7216           0 :   fail:
    7217             : 
    7218           0 :         if (cli) {
    7219           0 :                 if (fnum != (uint16_t)-1) {
    7220           0 :                         cli_close(cli, fnum);
    7221             :                 }
    7222           0 :                 cli_unlink(cli, fname,
    7223             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7224           0 :                 torture_close_connection(cli);
    7225             :         }
    7226             : 
    7227           0 :         TALLOC_FREE(frame);
    7228           0 :         return false;
    7229             : }
    7230             : 
    7231           0 : static bool run_pipe_number(int dummy)
    7232             : {
    7233             :         struct cli_state *cli1;
    7234           0 :         const char *pipe_name = "\\SPOOLSS";
    7235             :         uint16_t fnum;
    7236           0 :         int num_pipes = 0;
    7237             :         NTSTATUS status;
    7238             : 
    7239           0 :         printf("starting pipenumber test\n");
    7240           0 :         if (!torture_open_connection(&cli1, 0)) {
    7241           0 :                 return False;
    7242             :         }
    7243             : 
    7244           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7245             :         while(1) {
    7246           0 :                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
    7247             :                                       FILE_ATTRIBUTE_NORMAL,
    7248             :                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
    7249             :                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
    7250           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7251           0 :                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
    7252           0 :                         break;
    7253             :                 }
    7254           0 :                 num_pipes++;
    7255           0 :                 printf("\r%6d", num_pipes);
    7256             :         }
    7257             : 
    7258           0 :         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
    7259           0 :         torture_close_connection(cli1);
    7260           0 :         return True;
    7261             : }
    7262             : 
    7263             : /*
    7264             :   Test open mode returns on read-only files.
    7265             :  */
    7266           1 : static bool run_opentest(int dummy)
    7267             : {
    7268             :         static struct cli_state *cli1;
    7269             :         static struct cli_state *cli2;
    7270           1 :         const char *fname = "\\readonly.file";
    7271             :         uint16_t fnum1, fnum2;
    7272             :         char buf[20];
    7273             :         off_t fsize;
    7274           1 :         bool correct = True;
    7275             :         char *tmp_path;
    7276             :         NTSTATUS status;
    7277             : 
    7278           1 :         printf("starting open test\n");
    7279             : 
    7280           1 :         if (!torture_open_connection(&cli1, 0)) {
    7281           0 :                 return False;
    7282             :         }
    7283             : 
    7284           1 :         cli_setatr(cli1, fname, 0, 0);
    7285           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7286             : 
    7287           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7288             : 
    7289           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7290           1 :         if (!NT_STATUS_IS_OK(status)) {
    7291           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7292           0 :                 return False;
    7293             :         }
    7294             : 
    7295           1 :         status = cli_close(cli1, fnum1);
    7296           1 :         if (!NT_STATUS_IS_OK(status)) {
    7297           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7298           0 :                 return False;
    7299             :         }
    7300             : 
    7301           1 :         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
    7302           1 :         if (!NT_STATUS_IS_OK(status)) {
    7303           0 :                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
    7304           0 :                 return False;
    7305             :         }
    7306             : 
    7307           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7308           1 :         if (!NT_STATUS_IS_OK(status)) {
    7309           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7310           0 :                 return False;
    7311             :         }
    7312             : 
    7313             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
    7314           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7315             : 
    7316           1 :         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
    7317           1 :                         NT_STATUS_ACCESS_DENIED)) {
    7318           0 :                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
    7319             :         }
    7320             : 
    7321           1 :         printf("finished open test 1\n");
    7322             : 
    7323           1 :         cli_close(cli1, fnum1);
    7324             : 
    7325             :         /* Now try not readonly and ensure ERRbadshare is returned. */
    7326             : 
    7327           1 :         cli_setatr(cli1, fname, 0, 0);
    7328             : 
    7329           1 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7330           1 :         if (!NT_STATUS_IS_OK(status)) {
    7331           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7332           0 :                 return False;
    7333             :         }
    7334             : 
    7335             :         /* This will fail - but the error should be ERRshare. */
    7336           1 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7337             : 
    7338           1 :         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
    7339           1 :                         NT_STATUS_SHARING_VIOLATION)) {
    7340           1 :                 printf("correct error code ERRDOS/ERRbadshare returned\n");
    7341             :         }
    7342             : 
    7343           1 :         status = cli_close(cli1, fnum1);
    7344           1 :         if (!NT_STATUS_IS_OK(status)) {
    7345           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7346           0 :                 return False;
    7347             :         }
    7348             : 
    7349           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7350             : 
    7351           1 :         printf("finished open test 2\n");
    7352             : 
    7353             :         /* Test truncate open disposition on file opened for read. */
    7354           1 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7355           1 :         if (!NT_STATUS_IS_OK(status)) {
    7356           0 :                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
    7357           0 :                 return False;
    7358             :         }
    7359             : 
    7360             :         /* write 20 bytes. */
    7361             : 
    7362           1 :         memset(buf, '\0', 20);
    7363             : 
    7364           1 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
    7365           1 :         if (!NT_STATUS_IS_OK(status)) {
    7366           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    7367           0 :                 correct = False;
    7368             :         }
    7369             : 
    7370           1 :         status = cli_close(cli1, fnum1);
    7371           1 :         if (!NT_STATUS_IS_OK(status)) {
    7372           0 :                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
    7373           0 :                 return False;
    7374             :         }
    7375             : 
    7376             :         /* Ensure size == 20. */
    7377           1 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7378           1 :         if (!NT_STATUS_IS_OK(status)) {
    7379           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7380           0 :                 return False;
    7381             :         }
    7382             : 
    7383           1 :         if (fsize != 20) {
    7384           0 :                 printf("(3) file size != 20\n");
    7385           0 :                 return False;
    7386             :         }
    7387             : 
    7388             :         /* Now test if we can truncate a file opened for readonly. */
    7389           1 :         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
    7390           1 :         if (!NT_STATUS_IS_OK(status)) {
    7391           0 :                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
    7392           0 :                 return False;
    7393             :         }
    7394             : 
    7395           1 :         status = cli_close(cli1, fnum1);
    7396           1 :         if (!NT_STATUS_IS_OK(status)) {
    7397           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7398           0 :                 return False;
    7399             :         }
    7400             : 
    7401             :         /* Ensure size == 0. */
    7402           1 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7403           1 :         if (!NT_STATUS_IS_OK(status)) {
    7404           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7405           0 :                 return False;
    7406             :         }
    7407             : 
    7408           1 :         if (fsize != 0) {
    7409           0 :                 printf("(3) file size != 0\n");
    7410           0 :                 return False;
    7411             :         }
    7412           1 :         printf("finished open test 3\n");
    7413             : 
    7414           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7415             : 
    7416           1 :         printf("Do ctemp tests\n");
    7417           1 :         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
    7418           1 :         if (!NT_STATUS_IS_OK(status)) {
    7419           0 :                 printf("ctemp failed (%s)\n", nt_errstr(status));
    7420           0 :                 return False;
    7421             :         }
    7422             : 
    7423           1 :         printf("ctemp gave path %s\n", tmp_path);
    7424           1 :         status = cli_close(cli1, fnum1);
    7425           1 :         if (!NT_STATUS_IS_OK(status)) {
    7426           0 :                 printf("close of temp failed (%s)\n", nt_errstr(status));
    7427             :         }
    7428             : 
    7429           1 :         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7430           1 :         if (!NT_STATUS_IS_OK(status)) {
    7431           0 :                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
    7432             :         }
    7433             : 
    7434             :         /* Test the non-io opens... */
    7435             : 
    7436           1 :         if (!torture_open_connection(&cli2, 1)) {
    7437           0 :                 return False;
    7438             :         }
    7439             : 
    7440           1 :         cli_setatr(cli2, fname, 0, 0);
    7441           1 :         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7442             : 
    7443           1 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    7444             : 
    7445           1 :         printf("TEST #1 testing 2 non-io opens (no delete)\n");
    7446           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7447             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7448             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7449           1 :         if (!NT_STATUS_IS_OK(status)) {
    7450           0 :                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7451           0 :                 return False;
    7452             :         }
    7453             : 
    7454           1 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7455             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7456             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7457           1 :         if (!NT_STATUS_IS_OK(status)) {
    7458           0 :                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7459           0 :                 return False;
    7460             :         }
    7461             : 
    7462           1 :         status = cli_close(cli1, fnum1);
    7463           1 :         if (!NT_STATUS_IS_OK(status)) {
    7464           0 :                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7465           0 :                 return False;
    7466             :         }
    7467             : 
    7468           1 :         status = cli_close(cli2, fnum2);
    7469           1 :         if (!NT_STATUS_IS_OK(status)) {
    7470           0 :                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7471           0 :                 return False;
    7472             :         }
    7473             : 
    7474           1 :         printf("non-io open test #1 passed.\n");
    7475             : 
    7476           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7477             : 
    7478           1 :         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
    7479             : 
    7480           1 :         status = cli_ntcreate(cli1, fname, 0,
    7481             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7482             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7483             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7484           1 :         if (!NT_STATUS_IS_OK(status)) {
    7485           0 :                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7486           0 :                 return False;
    7487             :         }
    7488             : 
    7489           1 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7490             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7491             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7492           1 :         if (!NT_STATUS_IS_OK(status)) {
    7493           0 :                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7494           0 :                 return False;
    7495             :         }
    7496             : 
    7497           1 :         status = cli_close(cli1, fnum1);
    7498           1 :         if (!NT_STATUS_IS_OK(status)) {
    7499           0 :                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7500           0 :                 return False;
    7501             :         }
    7502             : 
    7503           1 :         status = cli_close(cli2, fnum2);
    7504           1 :         if (!NT_STATUS_IS_OK(status)) {
    7505           0 :                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7506           0 :                 return False;
    7507             :         }
    7508             : 
    7509           1 :         printf("non-io open test #2 passed.\n");
    7510             : 
    7511           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7512             : 
    7513           1 :         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
    7514             : 
    7515           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7516             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7517             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7518           1 :         if (!NT_STATUS_IS_OK(status)) {
    7519           0 :                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7520           0 :                 return False;
    7521             :         }
    7522             : 
    7523           1 :         status = cli_ntcreate(cli2, fname, 0,
    7524             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7525             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7526             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7527           1 :         if (!NT_STATUS_IS_OK(status)) {
    7528           0 :                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7529           0 :                 return False;
    7530             :         }
    7531             : 
    7532           1 :         status = cli_close(cli1, fnum1);
    7533           1 :         if (!NT_STATUS_IS_OK(status)) {
    7534           0 :                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7535           0 :                 return False;
    7536             :         }
    7537             : 
    7538           1 :         status = cli_close(cli2, fnum2);
    7539           1 :         if (!NT_STATUS_IS_OK(status)) {
    7540           0 :                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7541           0 :                 return False;
    7542             :         }
    7543             : 
    7544           1 :         printf("non-io open test #3 passed.\n");
    7545             : 
    7546           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7547             : 
    7548           1 :         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
    7549             : 
    7550           1 :         status = cli_ntcreate(cli1, fname, 0,
    7551             :                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7552             :                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7553             :                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7554           1 :         if (!NT_STATUS_IS_OK(status)) {
    7555           0 :                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7556           0 :                 return False;
    7557             :         }
    7558             : 
    7559           1 :         status = cli_ntcreate(cli2, fname, 0,
    7560             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7561             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7562             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7563           1 :         if (NT_STATUS_IS_OK(status)) {
    7564           0 :                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7565           0 :                 return False;
    7566             :         }
    7567             : 
    7568           1 :         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7569             : 
    7570           1 :         status = cli_close(cli1, fnum1);
    7571           1 :         if (!NT_STATUS_IS_OK(status)) {
    7572           0 :                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7573           0 :                 return False;
    7574             :         }
    7575             : 
    7576           1 :         printf("non-io open test #4 passed.\n");
    7577             : 
    7578           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7579             : 
    7580           1 :         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    7581             : 
    7582           1 :         status = cli_ntcreate(cli1, fname, 0,
    7583             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7584             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7585             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7586           1 :         if (!NT_STATUS_IS_OK(status)) {
    7587           0 :                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7588           0 :                 return False;
    7589             :         }
    7590             : 
    7591           1 :         status = cli_ntcreate(cli2, fname, 0,
    7592             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7593             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7594             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7595           1 :         if (!NT_STATUS_IS_OK(status)) {
    7596           0 :                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7597           0 :                 return False;
    7598             :         }
    7599             : 
    7600           1 :         status = cli_close(cli1, fnum1);
    7601           1 :         if (!NT_STATUS_IS_OK(status)) {
    7602           0 :                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7603           0 :                 return False;
    7604             :         }
    7605             : 
    7606           1 :         status = cli_close(cli2, fnum2);
    7607           1 :         if (!NT_STATUS_IS_OK(status)) {
    7608           0 :                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7609           0 :                 return False;
    7610             :         }
    7611             : 
    7612           1 :         printf("non-io open test #5 passed.\n");
    7613             : 
    7614           1 :         printf("TEST #6 testing 1 non-io open, one io open\n");
    7615             : 
    7616           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7617             : 
    7618           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7619             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7620             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7621           1 :         if (!NT_STATUS_IS_OK(status)) {
    7622           0 :                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7623           0 :                 return False;
    7624             :         }
    7625             : 
    7626           1 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7627             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    7628             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7629           1 :         if (!NT_STATUS_IS_OK(status)) {
    7630           0 :                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7631           0 :                 return False;
    7632             :         }
    7633             : 
    7634           1 :         status = cli_close(cli1, fnum1);
    7635           1 :         if (!NT_STATUS_IS_OK(status)) {
    7636           0 :                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7637           0 :                 return False;
    7638             :         }
    7639             : 
    7640           1 :         status = cli_close(cli2, fnum2);
    7641           1 :         if (!NT_STATUS_IS_OK(status)) {
    7642           0 :                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7643           0 :                 return False;
    7644             :         }
    7645             : 
    7646           1 :         printf("non-io open test #6 passed.\n");
    7647             : 
    7648           1 :         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
    7649             : 
    7650           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7651             : 
    7652           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7653             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7654             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7655           1 :         if (!NT_STATUS_IS_OK(status)) {
    7656           0 :                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7657           0 :                 return False;
    7658             :         }
    7659             : 
    7660           1 :         status = cli_ntcreate(cli2, fname, 0,
    7661             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7662             :                               FILE_ATTRIBUTE_NORMAL,
    7663             :                               FILE_SHARE_READ|FILE_SHARE_DELETE,
    7664             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7665           1 :         if (NT_STATUS_IS_OK(status)) {
    7666           0 :                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7667           0 :                 return False;
    7668             :         }
    7669             : 
    7670           1 :         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7671             : 
    7672           1 :         status = cli_close(cli1, fnum1);
    7673           1 :         if (!NT_STATUS_IS_OK(status)) {
    7674           0 :                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7675           0 :                 return False;
    7676             :         }
    7677             : 
    7678           1 :         printf("non-io open test #7 passed.\n");
    7679             : 
    7680           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7681             : 
    7682           1 :         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
    7683           1 :         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
    7684             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7685             :                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7686           1 :         if (!NT_STATUS_IS_OK(status)) {
    7687           0 :                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
    7688           0 :                 correct = false;
    7689           0 :                 goto out;
    7690             :         }
    7691             : 
    7692             :         /* Write to ensure we have to update the file time. */
    7693           1 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7694             :                               NULL);
    7695           1 :         if (!NT_STATUS_IS_OK(status)) {
    7696           0 :                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
    7697           0 :                 correct = false;
    7698           0 :                 goto out;
    7699             :         }
    7700             : 
    7701           1 :         status = cli_close(cli1, fnum1);
    7702           1 :         if (!NT_STATUS_IS_OK(status)) {
    7703           0 :                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
    7704           0 :                 correct = false;
    7705             :         }
    7706             : 
    7707           2 :   out:
    7708             : 
    7709           1 :         if (!torture_close_connection(cli1)) {
    7710           0 :                 correct = False;
    7711             :         }
    7712           1 :         if (!torture_close_connection(cli2)) {
    7713           0 :                 correct = False;
    7714             :         }
    7715             : 
    7716           1 :         return correct;
    7717             : }
    7718             : 
    7719           0 : NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
    7720             : {
    7721             :         uint16_t major, minor;
    7722             :         uint32_t caplow, caphigh;
    7723             :         NTSTATUS status;
    7724             : 
    7725           0 :         if (!SERVER_HAS_UNIX_CIFS(cli)) {
    7726           0 :                 printf("Server doesn't support UNIX CIFS extensions.\n");
    7727           0 :                 return NT_STATUS_NOT_SUPPORTED;
    7728             :         }
    7729             : 
    7730           0 :         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
    7731             :                                              &caphigh);
    7732           0 :         if (!NT_STATUS_IS_OK(status)) {
    7733           0 :                 printf("Server didn't return UNIX CIFS extensions: %s\n",
    7734             :                        nt_errstr(status));
    7735           0 :                 return status;
    7736             :         }
    7737             : 
    7738           0 :         status = cli_set_unix_extensions_capabilities(cli, major, minor,
    7739             :                                                       caplow, caphigh);
    7740           0 :         if (!NT_STATUS_IS_OK(status)) {
    7741           0 :                 printf("Server doesn't support setting UNIX CIFS extensions: "
    7742             :                        "%s.\n", nt_errstr(status));
    7743           0 :                 return status;
    7744             :         }
    7745             : 
    7746           0 :         return NT_STATUS_OK;
    7747             : }
    7748             : 
    7749             : /*
    7750             :   Test POSIX open /mkdir calls.
    7751             :  */
    7752           0 : static bool run_simple_posix_open_test(int dummy)
    7753             : {
    7754             :         static struct cli_state *cli1;
    7755           0 :         const char *fname = "posix:file";
    7756           0 :         const char *hname = "posix:hlink";
    7757           0 :         const char *sname = "posix:symlink";
    7758           0 :         const char *dname = "posix:dir";
    7759             :         char buf[10];
    7760           0 :         char *target = NULL;
    7761           0 :         uint16_t fnum1 = (uint16_t)-1;
    7762             :         SMB_STRUCT_STAT sbuf;
    7763           0 :         bool correct = false;
    7764             :         NTSTATUS status;
    7765             :         size_t nread;
    7766           0 :         const char *fname_windows = "windows_file";
    7767           0 :         uint16_t fnum2 = (uint16_t)-1;
    7768             : 
    7769           0 :         printf("Starting simple POSIX open test\n");
    7770             : 
    7771           0 :         if (!torture_open_connection(&cli1, 0)) {
    7772           0 :                 return false;
    7773             :         }
    7774             : 
    7775           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7776             : 
    7777           0 :         status = torture_setup_unix_extensions(cli1);
    7778           0 :         if (!NT_STATUS_IS_OK(status)) {
    7779           0 :                 return false;
    7780             :         }
    7781             : 
    7782           0 :         cli_setatr(cli1, fname, 0, 0);
    7783           0 :         cli_posix_unlink(cli1, fname);
    7784           0 :         cli_setatr(cli1, dname, 0, 0);
    7785           0 :         cli_posix_rmdir(cli1, dname);
    7786           0 :         cli_setatr(cli1, hname, 0, 0);
    7787           0 :         cli_posix_unlink(cli1, hname);
    7788           0 :         cli_setatr(cli1, sname, 0, 0);
    7789           0 :         cli_posix_unlink(cli1, sname);
    7790           0 :         cli_setatr(cli1, fname_windows, 0, 0);
    7791           0 :         cli_posix_unlink(cli1, fname_windows);
    7792             : 
    7793             :         /* Create a directory. */
    7794           0 :         status = cli_posix_mkdir(cli1, dname, 0777);
    7795           0 :         if (!NT_STATUS_IS_OK(status)) {
    7796           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7797           0 :                 goto out;
    7798             :         }
    7799             : 
    7800           0 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7801             :                                 0600, &fnum1);
    7802           0 :         if (!NT_STATUS_IS_OK(status)) {
    7803           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7804           0 :                 goto out;
    7805             :         }
    7806             : 
    7807             :         /* Test ftruncate - set file size. */
    7808           0 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7809           0 :         if (!NT_STATUS_IS_OK(status)) {
    7810           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7811           0 :                 goto out;
    7812             :         }
    7813             : 
    7814             :         /* Ensure st_size == 1000 */
    7815           0 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7816           0 :         if (!NT_STATUS_IS_OK(status)) {
    7817           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7818           0 :                 goto out;
    7819             :         }
    7820             : 
    7821           0 :         if (sbuf.st_ex_size != 1000) {
    7822           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7823           0 :                 goto out;
    7824             :         }
    7825             : 
    7826             :         /* Ensure st_mode == 0600 */
    7827           0 :         if ((sbuf.st_ex_mode & 07777) != 0600) {
    7828           0 :                 printf("posix_open - bad permissions 0%o != 0600\n",
    7829           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7830           0 :                 goto out;
    7831             :         }
    7832             : 
    7833             :         /* Test ftruncate - set file size back to zero. */
    7834           0 :         status = cli_ftruncate(cli1, fnum1, 0);
    7835           0 :         if (!NT_STATUS_IS_OK(status)) {
    7836           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7837           0 :                 goto out;
    7838             :         }
    7839             : 
    7840           0 :         status = cli_close(cli1, fnum1);
    7841           0 :         if (!NT_STATUS_IS_OK(status)) {
    7842           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7843           0 :                 goto out;
    7844             :         }
    7845             : 
    7846             :         /* Now open the file again for read only. */
    7847           0 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7848           0 :         if (!NT_STATUS_IS_OK(status)) {
    7849           0 :                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
    7850           0 :                 goto out;
    7851             :         }
    7852             : 
    7853             :         /* Now unlink while open. */
    7854           0 :         status = cli_posix_unlink(cli1, fname);
    7855           0 :         if (!NT_STATUS_IS_OK(status)) {
    7856           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7857           0 :                 goto out;
    7858             :         }
    7859             : 
    7860           0 :         status = cli_close(cli1, fnum1);
    7861           0 :         if (!NT_STATUS_IS_OK(status)) {
    7862           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7863           0 :                 goto out;
    7864             :         }
    7865             : 
    7866             :         /* Ensure the file has gone. */
    7867           0 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7868           0 :         if (NT_STATUS_IS_OK(status)) {
    7869           0 :                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
    7870           0 :                 goto out;
    7871             :         }
    7872             : 
    7873             :         /* Create again to test open with O_TRUNC. */
    7874           0 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
    7875           0 :         if (!NT_STATUS_IS_OK(status)) {
    7876           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7877           0 :                 goto out;
    7878             :         }
    7879             : 
    7880             :         /* Test ftruncate - set file size. */
    7881           0 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7882           0 :         if (!NT_STATUS_IS_OK(status)) {
    7883           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7884           0 :                 goto out;
    7885             :         }
    7886             : 
    7887             :         /* Ensure st_size == 1000 */
    7888           0 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7889           0 :         if (!NT_STATUS_IS_OK(status)) {
    7890           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7891           0 :                 goto out;
    7892             :         }
    7893             : 
    7894           0 :         if (sbuf.st_ex_size != 1000) {
    7895           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7896           0 :                 goto out;
    7897             :         }
    7898             : 
    7899           0 :         status = cli_close(cli1, fnum1);
    7900           0 :         if (!NT_STATUS_IS_OK(status)) {
    7901           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7902           0 :                 goto out;
    7903             :         }
    7904             : 
    7905             :         /* Re-open with O_TRUNC. */
    7906           0 :         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
    7907           0 :         if (!NT_STATUS_IS_OK(status)) {
    7908           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7909           0 :                 goto out;
    7910             :         }
    7911             : 
    7912             :         /* Ensure st_size == 0 */
    7913           0 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7914           0 :         if (!NT_STATUS_IS_OK(status)) {
    7915           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7916           0 :                 goto out;
    7917             :         }
    7918             : 
    7919           0 :         if (sbuf.st_ex_size != 0) {
    7920           0 :                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
    7921           0 :                 goto out;
    7922             :         }
    7923             : 
    7924           0 :         status = cli_close(cli1, fnum1);
    7925           0 :         if (!NT_STATUS_IS_OK(status)) {
    7926           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7927           0 :                 goto out;
    7928             :         }
    7929             : 
    7930           0 :         status = cli_posix_unlink(cli1, fname);
    7931           0 :         if (!NT_STATUS_IS_OK(status)) {
    7932           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7933           0 :                 goto out;
    7934             :         }
    7935             : 
    7936           0 :         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
    7937           0 :         if (!NT_STATUS_IS_OK(status)) {
    7938           0 :                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
    7939             :                         dname, nt_errstr(status));
    7940           0 :                 goto out;
    7941             :         }
    7942             : 
    7943           0 :         cli_close(cli1, fnum1);
    7944             : 
    7945             :         /* What happens when we try and POSIX open a directory for write ? */
    7946           0 :         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
    7947           0 :         if (NT_STATUS_IS_OK(status)) {
    7948           0 :                 printf("POSIX open of directory %s succeeded, "
    7949             :                        "should have failed.\n",
    7950             :                        dname);
    7951           0 :                 goto out;
    7952             :         } else {
    7953           0 :                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
    7954           0 :                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
    7955           0 :                         goto out;
    7956             :                 }
    7957             :         }
    7958             : 
    7959             :         /* Create the file. */
    7960           0 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7961             :                                 0600, &fnum1);
    7962           0 :         if (!NT_STATUS_IS_OK(status)) {
    7963           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7964           0 :                 goto out;
    7965             :         }
    7966             : 
    7967             :         /* Write some data into it. */
    7968           0 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7969             :                               NULL);
    7970           0 :         if (!NT_STATUS_IS_OK(status)) {
    7971           0 :                 printf("cli_write failed: %s\n", nt_errstr(status));
    7972           0 :                 goto out;
    7973             :         }
    7974             : 
    7975           0 :         cli_close(cli1, fnum1);
    7976             : 
    7977             :         /* Now create a hardlink. */
    7978           0 :         status = cli_posix_hardlink(cli1, fname, hname);
    7979           0 :         if (!NT_STATUS_IS_OK(status)) {
    7980           0 :                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
    7981           0 :                 goto out;
    7982             :         }
    7983             : 
    7984             :         /* Now create a symlink. */
    7985           0 :         status = cli_posix_symlink(cli1, fname, sname);
    7986           0 :         if (!NT_STATUS_IS_OK(status)) {
    7987           0 :                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
    7988           0 :                 goto out;
    7989             :         }
    7990             : 
    7991             :         /* Open the hardlink for read. */
    7992           0 :         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
    7993           0 :         if (!NT_STATUS_IS_OK(status)) {
    7994           0 :                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
    7995           0 :                 goto out;
    7996             :         }
    7997             : 
    7998           0 :         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
    7999           0 :         if (!NT_STATUS_IS_OK(status)) {
    8000           0 :                 printf("POSIX read of %s failed (%s)\n", hname,
    8001             :                        nt_errstr(status));
    8002           0 :                 goto out;
    8003           0 :         } else if (nread != 10) {
    8004           0 :                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
    8005             :                        hname, (unsigned long)nread, 10);
    8006           0 :                 goto out;
    8007             :         }
    8008             : 
    8009           0 :         if (memcmp(buf, "TEST DATA\n", 10)) {
    8010           0 :                 printf("invalid data read from hardlink\n");
    8011           0 :                 goto out;
    8012             :         }
    8013             : 
    8014             :         /* Do a POSIX lock/unlock. */
    8015           0 :         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
    8016           0 :         if (!NT_STATUS_IS_OK(status)) {
    8017           0 :                 printf("POSIX lock failed %s\n", nt_errstr(status));
    8018           0 :                 goto out;
    8019             :         }
    8020             : 
    8021             :         /* Punch a hole in the locked area. */
    8022           0 :         status = cli_posix_unlock(cli1, fnum1, 10, 80);
    8023           0 :         if (!NT_STATUS_IS_OK(status)) {
    8024           0 :                 printf("POSIX unlock failed %s\n", nt_errstr(status));
    8025           0 :                 goto out;
    8026             :         }
    8027             : 
    8028           0 :         cli_close(cli1, fnum1);
    8029             : 
    8030             :         /* Open the symlink for read - this should fail. A POSIX
    8031             :            client should not be doing opens on a symlink. */
    8032           0 :         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
    8033           0 :         if (NT_STATUS_IS_OK(status)) {
    8034           0 :                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
    8035           0 :                 goto out;
    8036             :         } else {
    8037           0 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
    8038           0 :                                 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    8039           0 :                         printf("POSIX open of %s should have failed "
    8040             :                                 "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
    8041             :                                 "failed with %s instead.\n",
    8042             :                                 sname, nt_errstr(status));
    8043           0 :                         goto out;
    8044             :                 }
    8045             :         }
    8046             : 
    8047           0 :         status = cli_posix_readlink(cli1, sname, talloc_tos(), &target);
    8048           0 :         if (!NT_STATUS_IS_OK(status)) {
    8049           0 :                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
    8050           0 :                 goto out;
    8051             :         }
    8052             : 
    8053           0 :         if (strcmp(target, fname) != 0) {
    8054           0 :                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
    8055             :                         sname, fname, target);
    8056           0 :                 goto out;
    8057             :         }
    8058             : 
    8059           0 :         status = cli_posix_rmdir(cli1, dname);
    8060           0 :         if (!NT_STATUS_IS_OK(status)) {
    8061           0 :                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
    8062           0 :                 goto out;
    8063             :         }
    8064             : 
    8065             :         /* Check directory opens with a specific permission. */
    8066           0 :         status = cli_posix_mkdir(cli1, dname, 0700);
    8067           0 :         if (!NT_STATUS_IS_OK(status)) {
    8068           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    8069           0 :                 goto out;
    8070             :         }
    8071             : 
    8072             :         /* Ensure st_mode == 0700 */
    8073           0 :         status = cli_posix_stat(cli1, dname, &sbuf);
    8074           0 :         if (!NT_STATUS_IS_OK(status)) {
    8075           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    8076           0 :                 goto out;
    8077             :         }
    8078             : 
    8079           0 :         if ((sbuf.st_ex_mode & 07777) != 0700) {
    8080           0 :                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
    8081           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    8082           0 :                 goto out;
    8083             :         }
    8084             : 
    8085             :         /*
    8086             :          * Now create a Windows file, and attempt a POSIX unlink.
    8087             :          * This should fail with a sharing violation but due to:
    8088             :          *
    8089             :          * [Bug 9571] Unlink after open causes smbd to panic
    8090             :          *
    8091             :          * ensure we've fixed the lock ordering violation.
    8092             :          */
    8093             : 
    8094           0 :         status = cli_ntcreate(cli1, fname_windows, 0,
    8095             :                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
    8096             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8097             :                         FILE_CREATE,
    8098             :                         0x0, 0x0, &fnum2, NULL);
    8099           0 :         if (!NT_STATUS_IS_OK(status)) {
    8100           0 :                 printf("Windows create of %s failed (%s)\n", fname_windows,
    8101             :                         nt_errstr(status));
    8102           0 :                 goto out;
    8103             :         }
    8104             : 
    8105             :         /* Now try posix_unlink. */
    8106           0 :         status = cli_posix_unlink(cli1, fname_windows);
    8107           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8108           0 :                 printf("POSIX unlink of %s should fail "
    8109             :                         "with NT_STATUS_SHARING_VIOLATION "
    8110             :                         "got %s instead !\n",
    8111             :                         fname_windows,
    8112             :                         nt_errstr(status));
    8113           0 :                 goto out;
    8114             :         }
    8115             : 
    8116           0 :         cli_close(cli1, fnum2);
    8117             : 
    8118           0 :         printf("Simple POSIX open test passed\n");
    8119           0 :         correct = true;
    8120             : 
    8121           0 :   out:
    8122             : 
    8123           0 :         if (fnum1 != (uint16_t)-1) {
    8124           0 :                 cli_close(cli1, fnum1);
    8125           0 :                 fnum1 = (uint16_t)-1;
    8126             :         }
    8127             : 
    8128           0 :         if (fnum2 != (uint16_t)-1) {
    8129           0 :                 cli_close(cli1, fnum2);
    8130           0 :                 fnum2 = (uint16_t)-1;
    8131             :         }
    8132             : 
    8133           0 :         cli_setatr(cli1, sname, 0, 0);
    8134           0 :         cli_posix_unlink(cli1, sname);
    8135           0 :         cli_setatr(cli1, hname, 0, 0);
    8136           0 :         cli_posix_unlink(cli1, hname);
    8137           0 :         cli_setatr(cli1, fname, 0, 0);
    8138           0 :         cli_posix_unlink(cli1, fname);
    8139           0 :         cli_setatr(cli1, dname, 0, 0);
    8140           0 :         cli_posix_rmdir(cli1, dname);
    8141           0 :         cli_setatr(cli1, fname_windows, 0, 0);
    8142           0 :         cli_posix_unlink(cli1, fname_windows);
    8143             : 
    8144           0 :         if (!torture_close_connection(cli1)) {
    8145           0 :                 correct = false;
    8146             :         }
    8147             : 
    8148           0 :         return correct;
    8149             : }
    8150             : 
    8151             : /*
    8152             :   Test POSIX and Windows ACLs are rejected on symlinks.
    8153             :  */
    8154           0 : static bool run_acl_symlink_test(int dummy)
    8155             : {
    8156             :         static struct cli_state *cli;
    8157           0 :         const char *fname = "posix_file";
    8158           0 :         const char *sname = "posix_symlink";
    8159           0 :         uint16_t fnum = (uint16_t)-1;
    8160           0 :         bool correct = false;
    8161             :         NTSTATUS status;
    8162           0 :         char *posix_acl = NULL;
    8163           0 :         size_t posix_acl_len = 0;
    8164           0 :         char *posix_acl_sym = NULL;
    8165           0 :         size_t posix_acl_len_sym = 0;
    8166           0 :         struct security_descriptor *sd = NULL;
    8167           0 :         TALLOC_CTX *frame = NULL;
    8168             : 
    8169           0 :         frame = talloc_stackframe();
    8170             : 
    8171           0 :         printf("Starting acl symlink test\n");
    8172             : 
    8173           0 :         if (!torture_open_connection(&cli, 0)) {
    8174           0 :                 TALLOC_FREE(frame);
    8175           0 :                 return false;
    8176             :         }
    8177             : 
    8178           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8179             : 
    8180           0 :         status = torture_setup_unix_extensions(cli);
    8181           0 :         if (!NT_STATUS_IS_OK(status)) {
    8182           0 :                 TALLOC_FREE(frame);
    8183           0 :                 return false;
    8184             :         }
    8185             : 
    8186           0 :         cli_setatr(cli, fname, 0, 0);
    8187           0 :         cli_posix_unlink(cli, fname);
    8188           0 :         cli_setatr(cli, sname, 0, 0);
    8189           0 :         cli_posix_unlink(cli, sname);
    8190             : 
    8191           0 :         status = cli_ntcreate(cli,
    8192             :                         fname,
    8193             :                         0,
    8194             :                         READ_CONTROL_ACCESS,
    8195             :                         0,
    8196             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8197             :                         FILE_CREATE,
    8198             :                         0x0,
    8199             :                         0x0,
    8200             :                         &fnum,
    8201             :                         NULL);
    8202             : 
    8203           0 :         if (!NT_STATUS_IS_OK(status)) {
    8204           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8205             :                         fname,
    8206             :                         nt_errstr(status));
    8207           0 :                 goto out;
    8208             :         }
    8209             : 
    8210             :         /* Get the Windows ACL on the file. */
    8211           0 :         status = cli_query_secdesc(cli,
    8212             :                                 fnum,
    8213             :                                 frame,
    8214             :                                 &sd);
    8215           0 :         if (!NT_STATUS_IS_OK(status)) {
    8216           0 :                 printf("cli_query_secdesc failed (%s)\n",
    8217             :                         nt_errstr(status));
    8218           0 :                 goto out;
    8219             :         }
    8220             : 
    8221             :         /* Get the POSIX ACL on the file. */
    8222           0 :         status = cli_posix_getacl(cli,
    8223             :                                 fname,
    8224             :                                 frame,
    8225             :                                 &posix_acl_len,
    8226             :                                 &posix_acl);
    8227             : 
    8228           0 :         if (!NT_STATUS_IS_OK(status)) {
    8229           0 :                 printf("cli_posix_getacl failed (%s)\n",
    8230             :                         nt_errstr(status));
    8231           0 :                 goto out;
    8232             :         }
    8233             : 
    8234           0 :         status = cli_close(cli, fnum);
    8235           0 :         if (!NT_STATUS_IS_OK(status)) {
    8236           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8237           0 :                 goto out;
    8238             :         }
    8239           0 :         fnum = (uint16_t)-1;
    8240             : 
    8241             :         /* Now create a symlink. */
    8242           0 :         status = cli_posix_symlink(cli, fname, sname);
    8243           0 :         if (!NT_STATUS_IS_OK(status)) {
    8244           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8245             :                         sname,
    8246             :                         fname,
    8247             :                         nt_errstr(status));
    8248           0 :                 goto out;
    8249             :         }
    8250             : 
    8251             :         /* Open a handle on the symlink for SD set/get should fail. */
    8252           0 :         status = cli_ntcreate(cli,
    8253             :                         sname,
    8254             :                         0,
    8255             :                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
    8256             :                         0,
    8257             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8258             :                         FILE_OPEN,
    8259             :                         0x0,
    8260             :                         0x0,
    8261             :                         &fnum,
    8262             :                         NULL);
    8263             : 
    8264           0 :         if (NT_STATUS_IS_OK(status)) {
    8265           0 :                 printf("Symlink open for getsd/setsd of %s "
    8266             :                         "succeeded (should fail)\n",
    8267             :                         sname);
    8268           0 :                 goto out;
    8269             :         }
    8270             : 
    8271             :         /* Try a stat-open on the symlink, should also fail. */
    8272           0 :         status = cli_ntcreate(cli,
    8273             :                         sname,
    8274             :                         0,
    8275             :                         FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
    8276             :                         0,
    8277             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8278             :                         FILE_OPEN,
    8279             :                         0x0,
    8280             :                         0x0,
    8281             :                         &fnum,
    8282             :                         NULL);
    8283             : 
    8284           0 :         if (NT_STATUS_IS_OK(status)) {
    8285           0 :                 printf("Stat-open of symlink succeeded (should fail)\n");
    8286           0 :                 goto out;
    8287             :         }
    8288             : 
    8289             :         /* Get the POSIX ACL on the symlink pathname. Should fail. */
    8290           0 :         status = cli_posix_getacl(cli,
    8291             :                                 sname,
    8292             :                                 frame,
    8293             :                                 &posix_acl_len_sym,
    8294             :                                 &posix_acl_sym);
    8295             : 
    8296           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8297           0 :                 printf("cli_posix_getacl on a symlink gave %s. "
    8298             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8299             :                         nt_errstr(status));
    8300           0 :                 goto out;
    8301             :         }
    8302             : 
    8303             :         /* Set the POSIX ACL on the symlink pathname. Should fail. */
    8304           0 :         status = cli_posix_setacl(cli,
    8305             :                                 sname,
    8306             :                                 posix_acl,
    8307             :                                 posix_acl_len);
    8308             : 
    8309           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8310           0 :                 printf("cli_posix_setacl on a symlink gave %s. "
    8311             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8312             :                         nt_errstr(status));
    8313           0 :                 goto out;
    8314             :         }
    8315             : 
    8316           0 :         printf("ACL symlink test passed\n");
    8317           0 :         correct = true;
    8318             : 
    8319           0 :   out:
    8320             : 
    8321           0 :         if (fnum != (uint16_t)-1) {
    8322           0 :                 cli_close(cli, fnum);
    8323           0 :                 fnum = (uint16_t)-1;
    8324             :         }
    8325             : 
    8326           0 :         cli_setatr(cli, sname, 0, 0);
    8327           0 :         cli_posix_unlink(cli, sname);
    8328           0 :         cli_setatr(cli, fname, 0, 0);
    8329           0 :         cli_posix_unlink(cli, fname);
    8330             : 
    8331           0 :         if (!torture_close_connection(cli)) {
    8332           0 :                 correct = false;
    8333             :         }
    8334             : 
    8335           0 :         TALLOC_FREE(frame);
    8336           0 :         return correct;
    8337             : }
    8338             : 
    8339             : /*
    8340             :   Test POSIX can delete a file containing streams.
    8341             :  */
    8342           0 : static bool run_posix_stream_delete(int dummy)
    8343             : {
    8344           0 :         struct cli_state *cli1 = NULL;
    8345           0 :         struct cli_state *cli2 = NULL;
    8346           0 :         const char *fname = "streamfile";
    8347           0 :         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
    8348           0 :         uint16_t fnum1 = (uint16_t)-1;
    8349           0 :         bool correct = false;
    8350             :         NTSTATUS status;
    8351           0 :         TALLOC_CTX *frame = NULL;
    8352             : 
    8353           0 :         frame = talloc_stackframe();
    8354             : 
    8355           0 :         printf("Starting POSIX stream delete test\n");
    8356             : 
    8357           0 :         if (!torture_open_connection(&cli1, 0) ||
    8358           0 :                         !torture_open_connection(&cli2, 1)) {
    8359           0 :                 TALLOC_FREE(frame);
    8360           0 :                 return false;
    8361             :         }
    8362             : 
    8363           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8364           0 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    8365             : 
    8366           0 :         status = torture_setup_unix_extensions(cli2);
    8367           0 :         if (!NT_STATUS_IS_OK(status)) {
    8368           0 :                 goto out;
    8369             :         }
    8370             : 
    8371           0 :         cli_setatr(cli1, fname, 0, 0);
    8372           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8373             : 
    8374             :         /* Create the file. */
    8375           0 :         status = cli_ntcreate(cli1,
    8376             :                         fname,
    8377             :                         0,
    8378             :                         READ_CONTROL_ACCESS,
    8379             :                         0,
    8380             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8381             :                         FILE_CREATE,
    8382             :                         0x0,
    8383             :                         0x0,
    8384             :                         &fnum1,
    8385             :                         NULL);
    8386             : 
    8387           0 :         if (!NT_STATUS_IS_OK(status)) {
    8388           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8389             :                         fname,
    8390             :                         nt_errstr(status));
    8391           0 :                 goto out;
    8392             :         }
    8393             : 
    8394           0 :         status = cli_close(cli1, fnum1);
    8395           0 :         if (!NT_STATUS_IS_OK(status)) {
    8396           0 :                 printf("cli_close of %s failed (%s)\n",
    8397             :                         fname,
    8398             :                         nt_errstr(status));
    8399           0 :                 goto out;
    8400             :         }
    8401           0 :         fnum1 = (uint16_t)-1;
    8402             : 
    8403             :         /* Now create the stream. */
    8404           0 :         status = cli_ntcreate(cli1,
    8405             :                         stream_fname,
    8406             :                         0,
    8407             :                         FILE_WRITE_DATA,
    8408             :                         0,
    8409             :                         FILE_SHARE_READ|FILE_SHARE_WRITE,
    8410             :                         FILE_CREATE,
    8411             :                         0x0,
    8412             :                         0x0,
    8413             :                         &fnum1,
    8414             :                         NULL);
    8415             : 
    8416           0 :         if (!NT_STATUS_IS_OK(status)) {
    8417           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8418             :                         stream_fname,
    8419             :                         nt_errstr(status));
    8420           0 :                 goto out;
    8421             :         }
    8422             : 
    8423             :         /* Leave the stream handle open... */
    8424             : 
    8425             :         /* POSIX unlink should fail. */
    8426           0 :         status = cli_posix_unlink(cli2, fname);
    8427           0 :         if (NT_STATUS_IS_OK(status)) {
    8428           0 :                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
    8429             :                         fname);
    8430           0 :                 goto out;
    8431             :         }
    8432             : 
    8433           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8434           0 :                 printf("cli_posix_unlink of %s failed with (%s) "
    8435             :                         "should have been NT_STATUS_SHARING_VIOLATION\n",
    8436             :                         fname,
    8437             :                         nt_errstr(status));
    8438           0 :                 goto out;
    8439             :         }
    8440             : 
    8441             :         /* Close the stream handle. */
    8442           0 :         status = cli_close(cli1, fnum1);
    8443           0 :         if (!NT_STATUS_IS_OK(status)) {
    8444           0 :                 printf("cli_close of %s failed (%s)\n",
    8445             :                         stream_fname,
    8446             :                         nt_errstr(status));
    8447           0 :                 goto out;
    8448             :         }
    8449           0 :         fnum1 = (uint16_t)-1;
    8450             : 
    8451             :         /* POSIX unlink after stream handle closed should succeed. */
    8452           0 :         status = cli_posix_unlink(cli2, fname);
    8453           0 :         if (!NT_STATUS_IS_OK(status)) {
    8454           0 :                 printf("cli_posix_unlink of %s failed (%s)\n",
    8455             :                         fname,
    8456             :                         nt_errstr(status));
    8457           0 :                 goto out;
    8458             :         }
    8459             : 
    8460           0 :         printf("POSIX stream delete test passed\n");
    8461           0 :         correct = true;
    8462             : 
    8463           0 :   out:
    8464             : 
    8465           0 :         if (fnum1 != (uint16_t)-1) {
    8466           0 :                 cli_close(cli1, fnum1);
    8467           0 :                 fnum1 = (uint16_t)-1;
    8468             :         }
    8469             : 
    8470           0 :         cli_setatr(cli1, fname, 0, 0);
    8471           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8472             : 
    8473           0 :         if (!torture_close_connection(cli1)) {
    8474           0 :                 correct = false;
    8475             :         }
    8476           0 :         if (!torture_close_connection(cli2)) {
    8477           0 :                 correct = false;
    8478             :         }
    8479             : 
    8480           0 :         TALLOC_FREE(frame);
    8481           0 :         return correct;
    8482             : }
    8483             : 
    8484             : /*
    8485             :   Test setting EA's are rejected on symlinks.
    8486             :  */
    8487           0 : static bool run_ea_symlink_test(int dummy)
    8488             : {
    8489             :         static struct cli_state *cli;
    8490           0 :         const char *fname = "posix_file_ea";
    8491           0 :         const char *sname = "posix_symlink_ea";
    8492           0 :         const char *ea_name = "testea_name";
    8493           0 :         const char *ea_value = "testea_value";
    8494           0 :         uint16_t fnum = (uint16_t)-1;
    8495           0 :         bool correct = false;
    8496             :         NTSTATUS status;
    8497             :         size_t i, num_eas;
    8498           0 :         struct ea_struct *eas = NULL;
    8499           0 :         TALLOC_CTX *frame = NULL;
    8500             : 
    8501           0 :         frame = talloc_stackframe();
    8502             : 
    8503           0 :         printf("Starting EA symlink test\n");
    8504             : 
    8505           0 :         if (!torture_open_connection(&cli, 0)) {
    8506           0 :                 TALLOC_FREE(frame);
    8507           0 :                 return false;
    8508             :         }
    8509             : 
    8510           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8511             : 
    8512           0 :         status = torture_setup_unix_extensions(cli);
    8513           0 :         if (!NT_STATUS_IS_OK(status)) {
    8514           0 :                 TALLOC_FREE(frame);
    8515           0 :                 return false;
    8516             :         }
    8517             : 
    8518           0 :         cli_setatr(cli, fname, 0, 0);
    8519           0 :         cli_posix_unlink(cli, fname);
    8520           0 :         cli_setatr(cli, sname, 0, 0);
    8521           0 :         cli_posix_unlink(cli, sname);
    8522             : 
    8523           0 :         status = cli_ntcreate(cli,
    8524             :                         fname,
    8525             :                         0,
    8526             :                         READ_CONTROL_ACCESS,
    8527             :                         0,
    8528             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8529             :                         FILE_CREATE,
    8530             :                         0x0,
    8531             :                         0x0,
    8532             :                         &fnum,
    8533             :                         NULL);
    8534             : 
    8535           0 :         if (!NT_STATUS_IS_OK(status)) {
    8536           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8537             :                         fname,
    8538             :                         nt_errstr(status));
    8539           0 :                 goto out;
    8540             :         }
    8541             : 
    8542           0 :         status = cli_close(cli, fnum);
    8543           0 :         if (!NT_STATUS_IS_OK(status)) {
    8544           0 :                 printf("close failed (%s)\n",
    8545             :                         nt_errstr(status));
    8546           0 :                 goto out;
    8547             :         }
    8548           0 :         fnum = (uint16_t)-1;
    8549             : 
    8550             :         /* Set an EA on the path. */
    8551           0 :         status = cli_set_ea_path(cli,
    8552             :                                 fname,
    8553             :                                 ea_name,
    8554             :                                 ea_value,
    8555           0 :                                 strlen(ea_value)+1);
    8556             : 
    8557           0 :         if (!NT_STATUS_IS_OK(status)) {
    8558           0 :                 printf("cli_set_ea_path failed (%s)\n",
    8559             :                         nt_errstr(status));
    8560           0 :                 goto out;
    8561             :         }
    8562             : 
    8563             :         /* Now create a symlink. */
    8564           0 :         status = cli_posix_symlink(cli, fname, sname);
    8565           0 :         if (!NT_STATUS_IS_OK(status)) {
    8566           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8567             :                         sname,
    8568             :                         fname,
    8569             :                         nt_errstr(status));
    8570           0 :                 goto out;
    8571             :         }
    8572             : 
    8573             :         /* Get the EA list on the path. Should return value set. */
    8574           0 :         status = cli_get_ea_list_path(cli,
    8575             :                                 fname,
    8576             :                                 frame,
    8577             :                                 &num_eas,
    8578             :                                 &eas);
    8579             : 
    8580           0 :         if (!NT_STATUS_IS_OK(status)) {
    8581           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8582             :                         nt_errstr(status));
    8583           0 :                 goto out;
    8584             :         }
    8585             : 
    8586             :         /* Ensure the EA we set is there. */
    8587           0 :         for (i=0; i<num_eas; i++) {
    8588           0 :                 if (strcmp(eas[i].name, ea_name) == 0 &&
    8589           0 :                                 eas[i].value.length == strlen(ea_value)+1 &&
    8590           0 :                                 memcmp(eas[i].value.data,
    8591             :                                         ea_value,
    8592           0 :                                         eas[i].value.length) == 0) {
    8593           0 :                         break;
    8594             :                 }
    8595             :         }
    8596             : 
    8597           0 :         if (i == num_eas) {
    8598           0 :                 printf("Didn't find EA on pathname %s\n",
    8599             :                         fname);
    8600           0 :                 goto out;
    8601             :         }
    8602             : 
    8603           0 :         num_eas = 0;
    8604           0 :         TALLOC_FREE(eas);
    8605             : 
    8606             :         /* Get the EA list on the symlink. Should return empty list. */
    8607           0 :         status = cli_get_ea_list_path(cli,
    8608             :                                 sname,
    8609             :                                 frame,
    8610             :                                 &num_eas,
    8611             :                                 &eas);
    8612             : 
    8613           0 :         if (!NT_STATUS_IS_OK(status)) {
    8614           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8615             :                         nt_errstr(status));
    8616           0 :                 goto out;
    8617             :         }
    8618             : 
    8619           0 :         if (num_eas != 0) {
    8620           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8621             :                         nt_errstr(status));
    8622           0 :                 goto out;
    8623             :         }
    8624             : 
    8625             :         /* Set an EA on the symlink. Should fail. */
    8626           0 :         status = cli_set_ea_path(cli,
    8627             :                                 sname,
    8628             :                                 ea_name,
    8629             :                                 ea_value,
    8630           0 :                                 strlen(ea_value)+1);
    8631             : 
    8632           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8633           0 :                 printf("cli_set_ea_path on a symlink gave %s. "
    8634             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8635             :                         nt_errstr(status));
    8636           0 :                 goto out;
    8637             :         }
    8638             : 
    8639           0 :         printf("EA symlink test passed\n");
    8640           0 :         correct = true;
    8641             : 
    8642           0 :   out:
    8643             : 
    8644           0 :         if (fnum != (uint16_t)-1) {
    8645           0 :                 cli_close(cli, fnum);
    8646           0 :                 fnum = (uint16_t)-1;
    8647             :         }
    8648             : 
    8649           0 :         cli_setatr(cli, sname, 0, 0);
    8650           0 :         cli_posix_unlink(cli, sname);
    8651           0 :         cli_setatr(cli, fname, 0, 0);
    8652           0 :         cli_posix_unlink(cli, fname);
    8653             : 
    8654           0 :         if (!torture_close_connection(cli)) {
    8655           0 :                 correct = false;
    8656             :         }
    8657             : 
    8658           0 :         TALLOC_FREE(frame);
    8659           0 :         return correct;
    8660             : }
    8661             : 
    8662             : /*
    8663             :   Test POSIX locks are OFD-locks.
    8664             :  */
    8665           0 : static bool run_posix_ofd_lock_test(int dummy)
    8666             : {
    8667             :         static struct cli_state *cli;
    8668           0 :         const char *fname = "posix_file";
    8669           0 :         uint16_t fnum1 = (uint16_t)-1;
    8670           0 :         uint16_t fnum2 = (uint16_t)-1;
    8671           0 :         bool correct = false;
    8672             :         NTSTATUS status;
    8673           0 :         TALLOC_CTX *frame = NULL;
    8674             : 
    8675           0 :         frame = talloc_stackframe();
    8676             : 
    8677           0 :         printf("Starting POSIX ofd-lock test\n");
    8678             : 
    8679           0 :         if (!torture_open_connection(&cli, 0)) {
    8680           0 :                 TALLOC_FREE(frame);
    8681           0 :                 return false;
    8682             :         }
    8683             : 
    8684           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8685             : 
    8686           0 :         status = torture_setup_unix_extensions(cli);
    8687           0 :         if (!NT_STATUS_IS_OK(status)) {
    8688           0 :                 TALLOC_FREE(frame);
    8689           0 :                 return false;
    8690             :         }
    8691             : 
    8692           0 :         cli_setatr(cli, fname, 0, 0);
    8693           0 :         cli_posix_unlink(cli, fname);
    8694             : 
    8695             :         /* Open the file twice. */
    8696           0 :         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
    8697             :                                 0600, &fnum1);
    8698           0 :         if (!NT_STATUS_IS_OK(status)) {
    8699           0 :                 printf("First POSIX open of %s failed\n", fname);
    8700           0 :                 goto out;
    8701             :         }
    8702             : 
    8703           0 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
    8704           0 :         if (!NT_STATUS_IS_OK(status)) {
    8705           0 :                 printf("First POSIX open of %s failed\n", fname);
    8706           0 :                 goto out;
    8707             :         }
    8708             : 
    8709             :         /* Set a 0-50 lock on fnum1. */
    8710           0 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8711           0 :         if (!NT_STATUS_IS_OK(status)) {
    8712           0 :                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
    8713           0 :                 goto out;
    8714             :         }
    8715             : 
    8716             :         /* Set a 60-100 lock on fnum2. */
    8717           0 :         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
    8718           0 :         if (!NT_STATUS_IS_OK(status)) {
    8719           0 :                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
    8720           0 :                 goto out;
    8721             :         }
    8722             : 
    8723             :         /* close fnum1 - 0-50 lock should go away. */
    8724           0 :         status = cli_close(cli, fnum1);
    8725           0 :         if (!NT_STATUS_IS_OK(status)) {
    8726           0 :                 printf("close failed (%s)\n",
    8727             :                         nt_errstr(status));
    8728           0 :                 goto out;
    8729             :         }
    8730           0 :         fnum1 = (uint16_t)-1;
    8731             : 
    8732             :         /* Change the lock context. */
    8733           0 :         cli_setpid(cli, cli_getpid(cli) + 1);
    8734             : 
    8735             :         /* Re-open fnum1. */
    8736           0 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
    8737           0 :         if (!NT_STATUS_IS_OK(status)) {
    8738           0 :                 printf("Third POSIX open of %s failed\n", fname);
    8739           0 :                 goto out;
    8740             :         }
    8741             : 
    8742             :         /* 60-100 lock should still be there. */
    8743           0 :         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
    8744           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    8745           0 :                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
    8746           0 :                 goto out;
    8747             :         }
    8748             : 
    8749             :         /* 0-50 lock should be gone. */
    8750           0 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8751           0 :         if (!NT_STATUS_IS_OK(status)) {
    8752           0 :                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
    8753           0 :                 goto out;
    8754             :         }
    8755             : 
    8756           0 :         printf("POSIX OFD lock test passed\n");
    8757           0 :         correct = true;
    8758             : 
    8759           0 :   out:
    8760             : 
    8761           0 :         if (fnum1 != (uint16_t)-1) {
    8762           0 :                 cli_close(cli, fnum1);
    8763           0 :                 fnum1 = (uint16_t)-1;
    8764             :         }
    8765           0 :         if (fnum2 != (uint16_t)-1) {
    8766           0 :                 cli_close(cli, fnum2);
    8767           0 :                 fnum2 = (uint16_t)-1;
    8768             :         }
    8769             : 
    8770           0 :         cli_setatr(cli, fname, 0, 0);
    8771           0 :         cli_posix_unlink(cli, fname);
    8772             : 
    8773           0 :         if (!torture_close_connection(cli)) {
    8774           0 :                 correct = false;
    8775             :         }
    8776             : 
    8777           0 :         TALLOC_FREE(frame);
    8778           0 :         return correct;
    8779             : }
    8780             : 
    8781             : struct posix_blocking_state {
    8782             :         struct tevent_context *ev;
    8783             :         struct cli_state *cli1;
    8784             :         uint16_t fnum1;
    8785             :         struct cli_state *cli2;
    8786             :         uint16_t fnum2;
    8787             :         bool gotblocked;
    8788             :         bool gotecho;
    8789             : };
    8790             : 
    8791             : static void posix_blocking_locked(struct tevent_req *subreq);
    8792             : static void posix_blocking_gotblocked(struct tevent_req *subreq);
    8793             : static void posix_blocking_gotecho(struct tevent_req *subreq);
    8794             : static void posix_blocking_unlocked(struct tevent_req *subreq);
    8795             : 
    8796           0 : static struct tevent_req *posix_blocking_send(
    8797             :         TALLOC_CTX *mem_ctx,
    8798             :         struct tevent_context *ev,
    8799             :         struct cli_state *cli1,
    8800             :         uint16_t fnum1,
    8801             :         struct cli_state *cli2,
    8802             :         uint16_t fnum2)
    8803             : {
    8804           0 :         struct tevent_req *req = NULL, *subreq = NULL;
    8805           0 :         struct posix_blocking_state *state = NULL;
    8806             : 
    8807           0 :         req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
    8808           0 :         if (req == NULL) {
    8809           0 :                 return NULL;
    8810             :         }
    8811           0 :         state->ev = ev;
    8812           0 :         state->cli1 = cli1;
    8813           0 :         state->fnum1 = fnum1;
    8814           0 :         state->cli2 = cli2;
    8815           0 :         state->fnum2 = fnum2;
    8816             : 
    8817           0 :         subreq = cli_posix_lock_send(
    8818             :                 state,
    8819           0 :                 state->ev,
    8820           0 :                 state->cli1,
    8821           0 :                 state->fnum1,
    8822             :                 0,
    8823             :                 1,
    8824             :                 false,
    8825             :                 WRITE_LOCK);
    8826           0 :         if (tevent_req_nomem(subreq, req)) {
    8827           0 :                 return tevent_req_post(req, ev);
    8828             :         }
    8829           0 :         tevent_req_set_callback(subreq, posix_blocking_locked, req);
    8830           0 :         return req;
    8831             : }
    8832             : 
    8833           0 : static void posix_blocking_locked(struct tevent_req *subreq)
    8834             : {
    8835           0 :         struct tevent_req *req = tevent_req_callback_data(
    8836             :                 subreq, struct tevent_req);
    8837           0 :         struct posix_blocking_state *state = tevent_req_data(
    8838             :                 req, struct posix_blocking_state);
    8839             :         NTSTATUS status;
    8840             : 
    8841           0 :         status = cli_posix_lock_recv(subreq);
    8842           0 :         TALLOC_FREE(subreq);
    8843           0 :         if (tevent_req_nterror(req, status)) {
    8844           0 :                 return;
    8845             :         }
    8846             : 
    8847           0 :         subreq = cli_posix_lock_send(
    8848             :                 state,
    8849             :                 state->ev,
    8850             :                 state->cli2,
    8851           0 :                 state->fnum2,
    8852             :                 0,
    8853             :                 1,
    8854             :                 true,
    8855             :                 WRITE_LOCK);
    8856           0 :         if (tevent_req_nomem(subreq, req)) {
    8857           0 :                 return;
    8858             :         }
    8859           0 :         tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
    8860             : 
    8861             :         /* Make sure the blocking request is delivered */
    8862           0 :         subreq = cli_echo_send(
    8863             :                 state,
    8864             :                 state->ev,
    8865             :                 state->cli2,
    8866             :                 1,
    8867           0 :                 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
    8868           0 :         if (tevent_req_nomem(subreq, req)) {
    8869           0 :                 return;
    8870             :         }
    8871           0 :         tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
    8872             : }
    8873             : 
    8874           0 : static void posix_blocking_gotblocked(struct tevent_req *subreq)
    8875             : {
    8876           0 :         struct tevent_req *req = tevent_req_callback_data(
    8877             :                 subreq, struct tevent_req);
    8878           0 :         struct posix_blocking_state *state = tevent_req_data(
    8879             :                 req, struct posix_blocking_state);
    8880             :         NTSTATUS status;
    8881             : 
    8882           0 :         status = cli_posix_lock_recv(subreq);
    8883           0 :         TALLOC_FREE(subreq);
    8884           0 :         if (tevent_req_nterror(req, status)) {
    8885           0 :                 return;
    8886             :         }
    8887           0 :         if (!state->gotecho) {
    8888           0 :                 printf("blocked req got through before echo\n");
    8889           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8890           0 :                 return;
    8891             :         }
    8892           0 :         tevent_req_done(req);
    8893             : }
    8894             : 
    8895           0 : static void posix_blocking_gotecho(struct tevent_req *subreq)
    8896             : {
    8897           0 :         struct tevent_req *req = tevent_req_callback_data(
    8898             :                 subreq, struct tevent_req);
    8899           0 :         struct posix_blocking_state *state = tevent_req_data(
    8900             :                 req, struct posix_blocking_state);
    8901             :         NTSTATUS status;
    8902             : 
    8903           0 :         status = cli_echo_recv(subreq);
    8904           0 :         TALLOC_FREE(subreq);
    8905           0 :         if (tevent_req_nterror(req, status)) {
    8906           0 :                 return;
    8907             :         }
    8908           0 :         if (state->gotblocked) {
    8909           0 :                 printf("blocked req got through before echo\n");
    8910           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8911           0 :                 return;
    8912             :         }
    8913           0 :         state->gotecho = true;
    8914             : 
    8915           0 :         subreq = cli_posix_lock_send(
    8916             :                 state,
    8917             :                 state->ev,
    8918             :                 state->cli1,
    8919           0 :                 state->fnum1,
    8920             :                 0,
    8921             :                 1,
    8922             :                 false,
    8923             :                 UNLOCK_LOCK);
    8924           0 :         if (tevent_req_nomem(subreq, req)) {
    8925           0 :                 return;
    8926             :         }
    8927           0 :         tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
    8928             : }
    8929             : 
    8930           0 : static void posix_blocking_unlocked(struct tevent_req *subreq)
    8931             : {
    8932           0 :         struct tevent_req *req = tevent_req_callback_data(
    8933             :                 subreq, struct tevent_req);
    8934             :         NTSTATUS status;
    8935             : 
    8936           0 :         status = cli_posix_lock_recv(subreq);
    8937           0 :         TALLOC_FREE(subreq);
    8938           0 :         if (tevent_req_nterror(req, status)) {
    8939           0 :                 return;
    8940             :         }
    8941             :         /* tevent_req_done in posix_blocking_gotlocked */
    8942             : }
    8943             : 
    8944           0 : static NTSTATUS posix_blocking_recv(struct tevent_req *req)
    8945             : {
    8946           0 :         return tevent_req_simple_recv_ntstatus(req);
    8947             : }
    8948             : 
    8949           0 : static bool run_posix_blocking_lock(int dummy)
    8950             : {
    8951           0 :         struct tevent_context *ev = NULL;
    8952           0 :         struct cli_state *cli1 = NULL, *cli2 = NULL;
    8953           0 :         const char *fname = "posix_blocking";
    8954           0 :         uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
    8955           0 :         struct tevent_req *req = NULL;
    8956             :         NTSTATUS status;
    8957           0 :         bool ret = false;
    8958             :         bool ok;
    8959             : 
    8960           0 :         printf("Starting posix blocking lock test\n");
    8961             : 
    8962           0 :         ev = samba_tevent_context_init(NULL);
    8963           0 :         if (ev == NULL) {
    8964           0 :                 return false;
    8965             :         }
    8966             : 
    8967           0 :         ok = torture_open_connection(&cli1, 0);
    8968           0 :         if (!ok) {
    8969           0 :                 goto fail;
    8970             :         }
    8971           0 :         ok = torture_open_connection(&cli2, 0);
    8972           0 :         if (!ok) {
    8973           0 :                 goto fail;
    8974             :         }
    8975             : 
    8976           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8977             : 
    8978           0 :         status = torture_setup_unix_extensions(cli1);
    8979           0 :         if (!NT_STATUS_IS_OK(status)) {
    8980           0 :                 return false;
    8981             :         }
    8982             : 
    8983           0 :         status = torture_setup_unix_extensions(cli2);
    8984           0 :         if (!NT_STATUS_IS_OK(status)) {
    8985           0 :                 return false;
    8986             :         }
    8987             : 
    8988           0 :         cli_setatr(cli1, fname, 0, 0);
    8989           0 :         cli_posix_unlink(cli1, fname);
    8990             : 
    8991           0 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    8992             :                                 0600, &fnum1);
    8993           0 :         if (!NT_STATUS_IS_OK(status)) {
    8994           0 :                 printf("First POSIX open of %s failed: %s\n",
    8995             :                        fname,
    8996             :                        nt_errstr(status));
    8997           0 :                 goto fail;
    8998             :         }
    8999             : 
    9000           0 :         status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
    9001           0 :         if (!NT_STATUS_IS_OK(status)) {
    9002           0 :                 printf("Second POSIX open of %s failed: %s\n",
    9003             :                        fname,
    9004             :                        nt_errstr(status));
    9005           0 :                 goto fail;
    9006             :         }
    9007             : 
    9008           0 :         req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
    9009           0 :         if (req == NULL) {
    9010           0 :                 printf("cli_posix_blocking failed\n");
    9011           0 :                 goto fail;
    9012             :         }
    9013             : 
    9014           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    9015           0 :         if (!ok) {
    9016           0 :                 printf("tevent_req_poll_ntstatus failed: %s\n",
    9017             :                        nt_errstr(status));
    9018           0 :                 goto fail;
    9019             :         }
    9020           0 :         status = posix_blocking_recv(req);
    9021           0 :         TALLOC_FREE(req);
    9022           0 :         if (!NT_STATUS_IS_OK(status)) {
    9023           0 :                 printf("posix_blocking_recv returned %s\n",
    9024             :                        nt_errstr(status));
    9025           0 :                 goto fail;
    9026             :         }
    9027             : 
    9028           0 :         ret = true;
    9029           0 : fail:
    9030             : 
    9031           0 :         if (fnum1 != UINT16_MAX) {
    9032           0 :                 cli_close(cli1, fnum1);
    9033           0 :                 fnum1 = UINT16_MAX;
    9034             :         }
    9035           0 :         if (fnum2 != UINT16_MAX) {
    9036           0 :                 cli_close(cli2, fnum2);
    9037           0 :                 fnum2 = UINT16_MAX;
    9038             :         }
    9039             : 
    9040           0 :         if (cli1 != NULL) {
    9041           0 :                 cli_setatr(cli1, fname, 0, 0);
    9042           0 :                 cli_posix_unlink(cli1, fname);
    9043             :         }
    9044             : 
    9045           0 :         ok = true;
    9046             : 
    9047           0 :         if (cli1 != NULL) {
    9048           0 :                 ok &= torture_close_connection(cli1);
    9049           0 :                 cli1 = NULL;
    9050             :         }
    9051           0 :         if (cli2 != NULL) {
    9052           0 :                 ok &= torture_close_connection(cli2);
    9053           0 :                 cli2 = NULL;
    9054             :         }
    9055             : 
    9056           0 :         if (!ok) {
    9057           0 :                 ret = false;
    9058             :         }
    9059           0 :         TALLOC_FREE(ev);
    9060           0 :         return ret;
    9061             : }
    9062             : 
    9063             : /*
    9064             :   Test POSIX mkdir is case-sensitive.
    9065             :  */
    9066           0 : static bool run_posix_mkdir_test(int dummy)
    9067             : {
    9068             :         static struct cli_state *cli;
    9069           0 :         const char *fname_foo = "POSIX_foo";
    9070           0 :         const char *fname_foo_Foo = "POSIX_foo/Foo";
    9071           0 :         const char *fname_foo_foo = "POSIX_foo/foo";
    9072           0 :         const char *fname_Foo = "POSIX_Foo";
    9073           0 :         const char *fname_Foo_Foo = "POSIX_Foo/Foo";
    9074           0 :         const char *fname_Foo_foo = "POSIX_Foo/foo";
    9075           0 :         bool correct = false;
    9076             :         NTSTATUS status;
    9077           0 :         TALLOC_CTX *frame = NULL;
    9078           0 :         uint16_t fnum = (uint16_t)-1;
    9079             : 
    9080           0 :         frame = talloc_stackframe();
    9081             : 
    9082           0 :         printf("Starting POSIX mkdir test\n");
    9083             : 
    9084           0 :         if (!torture_open_connection(&cli, 0)) {
    9085           0 :                 TALLOC_FREE(frame);
    9086           0 :                 return false;
    9087             :         }
    9088             : 
    9089           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9090             : 
    9091           0 :         status = torture_setup_unix_extensions(cli);
    9092           0 :         if (!NT_STATUS_IS_OK(status)) {
    9093           0 :                 TALLOC_FREE(frame);
    9094           0 :                 return false;
    9095             :         }
    9096             : 
    9097           0 :         cli_posix_rmdir(cli, fname_foo_foo);
    9098           0 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9099           0 :         cli_posix_rmdir(cli, fname_foo);
    9100             : 
    9101           0 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9102           0 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9103           0 :         cli_posix_rmdir(cli, fname_Foo);
    9104             : 
    9105             :         /*
    9106             :          * Create a file POSIX_foo then try
    9107             :          * and use it in a directory path by
    9108             :          * doing mkdir POSIX_foo/bar.
    9109             :          * The mkdir should fail with
    9110             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND
    9111             :          */
    9112             : 
    9113           0 :         status = cli_posix_open(cli,
    9114             :                         fname_foo,
    9115             :                         O_RDWR|O_CREAT,
    9116             :                         0666,
    9117             :                         &fnum);
    9118           0 :         if (!NT_STATUS_IS_OK(status)) {
    9119           0 :                 printf("cli_posix_open of %s failed error %s\n",
    9120             :                         fname_foo,
    9121             :                         nt_errstr(status));
    9122           0 :                 goto out;
    9123             :         }
    9124             : 
    9125           0 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9126           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9127           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9128             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9129             :                         "%s instead\n",
    9130             :                         fname_foo_foo,
    9131             :                         nt_errstr(status));
    9132           0 :                 goto out;
    9133             :         }
    9134             : 
    9135           0 :         status = cli_close(cli, fnum);
    9136           0 :         if (!NT_STATUS_IS_OK(status)) {
    9137           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    9138           0 :                 goto out;
    9139             :         }
    9140           0 :         fnum = (uint16_t)-1;
    9141             : 
    9142           0 :         status = cli_posix_unlink(cli, fname_foo);
    9143           0 :         if (!NT_STATUS_IS_OK(status)) {
    9144           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
    9145             :                         fname_foo,
    9146             :                         nt_errstr(status));
    9147           0 :                 goto out;
    9148             :         }
    9149             : 
    9150             :         /*
    9151             :          * Now we've deleted everything, posix_mkdir, posix_rmdir,
    9152             :          * posix_open, posix_unlink, on
    9153             :          * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
    9154             :          * not silently create POSIX_foo/foo.
    9155             :          */
    9156             : 
    9157           0 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9158           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9159           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9160             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9161             :                         "%s instead\n",
    9162             :                         fname_foo_foo,
    9163             :                         nt_errstr(status));
    9164           0 :                 goto out;
    9165             :         }
    9166             : 
    9167           0 :         status = cli_posix_rmdir(cli, fname_foo_foo);
    9168           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9169           0 :                 printf("cli_posix_rmdir of %s should fail with "
    9170             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9171             :                         "%s instead\n",
    9172             :                         fname_foo_foo,
    9173             :                         nt_errstr(status));
    9174           0 :                 goto out;
    9175             :         }
    9176             : 
    9177           0 :         status = cli_posix_open(cli,
    9178             :                         fname_foo_foo,
    9179             :                         O_RDWR|O_CREAT,
    9180             :                         0666,
    9181             :                         &fnum);
    9182           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9183           0 :                 printf("cli_posix_open of %s should fail with "
    9184             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9185             :                         "%s instead\n",
    9186             :                         fname_foo_foo,
    9187             :                         nt_errstr(status));
    9188           0 :                 goto out;
    9189             :         }
    9190             : 
    9191           0 :         status = cli_posix_unlink(cli, fname_foo_foo);
    9192           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9193           0 :                 printf("cli_posix_unlink of %s should fail with "
    9194             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9195             :                         "%s instead\n",
    9196             :                         fname_foo_foo,
    9197             :                         nt_errstr(status));
    9198           0 :                 goto out;
    9199             :         }
    9200             : 
    9201           0 :         status = cli_posix_mkdir(cli, fname_foo, 0777);
    9202           0 :         if (!NT_STATUS_IS_OK(status)) {
    9203           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo);
    9204           0 :                 goto out;
    9205             :         }
    9206             : 
    9207           0 :         status = cli_posix_mkdir(cli, fname_Foo, 0777);
    9208           0 :         if (!NT_STATUS_IS_OK(status)) {
    9209           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
    9210           0 :                 goto out;
    9211             :         }
    9212             : 
    9213           0 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9214           0 :         if (!NT_STATUS_IS_OK(status)) {
    9215           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
    9216           0 :                 goto out;
    9217             :         }
    9218             : 
    9219           0 :         status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
    9220           0 :         if (!NT_STATUS_IS_OK(status)) {
    9221           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
    9222           0 :                 goto out;
    9223             :         }
    9224             : 
    9225           0 :         status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
    9226           0 :         if (!NT_STATUS_IS_OK(status)) {
    9227           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
    9228           0 :                 goto out;
    9229             :         }
    9230             : 
    9231           0 :         status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
    9232           0 :         if (!NT_STATUS_IS_OK(status)) {
    9233           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
    9234           0 :                 goto out;
    9235             :         }
    9236             : 
    9237           0 :         printf("POSIX mkdir test passed\n");
    9238           0 :         correct = true;
    9239             : 
    9240           0 :   out:
    9241             : 
    9242           0 :         if (fnum != (uint16_t)-1) {
    9243           0 :                 cli_close(cli, fnum);
    9244           0 :                 fnum = (uint16_t)-1;
    9245             :         }
    9246             : 
    9247           0 :         cli_posix_rmdir(cli, fname_foo_foo);
    9248           0 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9249           0 :         cli_posix_rmdir(cli, fname_foo);
    9250             : 
    9251           0 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9252           0 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9253           0 :         cli_posix_rmdir(cli, fname_Foo);
    9254             : 
    9255           0 :         if (!torture_close_connection(cli)) {
    9256           0 :                 correct = false;
    9257             :         }
    9258             : 
    9259           0 :         TALLOC_FREE(frame);
    9260           0 :         return correct;
    9261             : }
    9262             : 
    9263             : struct posix_acl_oplock_state {
    9264             :         struct tevent_context *ev;
    9265             :         struct cli_state *cli;
    9266             :         bool *got_break;
    9267             :         bool *acl_ret;
    9268             :         NTSTATUS status;
    9269             : };
    9270             : 
    9271           0 : static void posix_acl_oplock_got_break(struct tevent_req *req)
    9272             : {
    9273           0 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9274             :                 req, struct posix_acl_oplock_state);
    9275             :         uint16_t fnum;
    9276             :         uint8_t level;
    9277             :         NTSTATUS status;
    9278             : 
    9279           0 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    9280           0 :         TALLOC_FREE(req);
    9281           0 :         if (!NT_STATUS_IS_OK(status)) {
    9282           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    9283             :                        nt_errstr(status));
    9284           0 :                 return;
    9285             :         }
    9286           0 :         *state->got_break = true;
    9287             : 
    9288           0 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    9289             :                                   NO_OPLOCK);
    9290           0 :         if (req == NULL) {
    9291           0 :                 printf("cli_oplock_ack_send failed\n");
    9292           0 :                 return;
    9293             :         }
    9294             : }
    9295             : 
    9296           0 : static void posix_acl_oplock_got_acl(struct tevent_req *req)
    9297             : {
    9298           0 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9299             :                 req, struct posix_acl_oplock_state);
    9300           0 :         size_t ret_size = 0;
    9301           0 :         char *ret_data = NULL;
    9302             : 
    9303           0 :         state->status = cli_posix_getacl_recv(req,
    9304             :                         state,
    9305             :                         &ret_size,
    9306             :                         &ret_data);
    9307             : 
    9308           0 :         if (!NT_STATUS_IS_OK(state->status)) {
    9309           0 :                 printf("cli_posix_getacl_recv returned %s\n",
    9310             :                         nt_errstr(state->status));
    9311             :         }
    9312           0 :         *state->acl_ret = true;
    9313           0 : }
    9314             : 
    9315           0 : static bool run_posix_acl_oplock_test(int dummy)
    9316             : {
    9317             :         struct tevent_context *ev;
    9318             :         struct cli_state *cli1, *cli2;
    9319             :         struct tevent_req *oplock_req, *getacl_req;
    9320           0 :         const char *fname = "posix_acl_oplock";
    9321             :         uint16_t fnum;
    9322           0 :         int saved_use_oplocks = use_oplocks;
    9323             :         NTSTATUS status;
    9324           0 :         bool correct = true;
    9325           0 :         bool got_break = false;
    9326           0 :         bool acl_ret = false;
    9327             : 
    9328             :         struct posix_acl_oplock_state *state;
    9329             : 
    9330           0 :         printf("starting posix_acl_oplock test\n");
    9331             : 
    9332           0 :         if (!torture_open_connection(&cli1, 0)) {
    9333           0 :                 use_level_II_oplocks = false;
    9334           0 :                 use_oplocks = saved_use_oplocks;
    9335           0 :                 return false;
    9336             :         }
    9337             : 
    9338           0 :         if (!torture_open_connection(&cli2, 1)) {
    9339           0 :                 use_level_II_oplocks = false;
    9340           0 :                 use_oplocks = saved_use_oplocks;
    9341           0 :                 return false;
    9342             :         }
    9343             : 
    9344             :         /* Setup posix on cli2 only. */
    9345           0 :         status = torture_setup_unix_extensions(cli2);
    9346           0 :         if (!NT_STATUS_IS_OK(status)) {
    9347           0 :                 return false;
    9348             :         }
    9349             : 
    9350           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9351           0 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    9352             : 
    9353           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9354             : 
    9355             :         /* Create the file on the Windows connection. */
    9356           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    9357             :                           &fnum);
    9358           0 :         if (!NT_STATUS_IS_OK(status)) {
    9359           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9360           0 :                 return false;
    9361             :         }
    9362             : 
    9363           0 :         status = cli_close(cli1, fnum);
    9364           0 :         if (!NT_STATUS_IS_OK(status)) {
    9365           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    9366           0 :                 return false;
    9367             :         }
    9368             : 
    9369           0 :         cli1->use_oplocks = true;
    9370             : 
    9371             :         /* Open with oplock. */
    9372           0 :         status = cli_ntcreate(cli1,
    9373             :                         fname,
    9374             :                         0,
    9375             :                         FILE_READ_DATA,
    9376             :                         FILE_ATTRIBUTE_NORMAL,
    9377             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    9378             :                         FILE_OPEN,
    9379             :                         0,
    9380             :                         0,
    9381             :                         &fnum,
    9382             :                         NULL);
    9383             : 
    9384           0 :         if (!NT_STATUS_IS_OK(status)) {
    9385           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9386           0 :                 return false;
    9387             :         }
    9388             : 
    9389           0 :         ev = samba_tevent_context_init(talloc_tos());
    9390           0 :         if (ev == NULL) {
    9391           0 :                 printf("tevent_context_init failed\n");
    9392           0 :                 return false;
    9393             :         }
    9394             : 
    9395           0 :         state = talloc_zero(ev, struct posix_acl_oplock_state);
    9396           0 :         if (state == NULL) {
    9397           0 :                 printf("talloc failed\n");
    9398           0 :                 return false;
    9399             :         }
    9400           0 :         state->ev = ev;
    9401           0 :         state->cli = cli1;
    9402           0 :         state->got_break = &got_break;
    9403           0 :         state->acl_ret = &acl_ret;
    9404             : 
    9405           0 :         oplock_req = cli_smb_oplock_break_waiter_send(
    9406             :                 talloc_tos(), ev, cli1);
    9407           0 :         if (oplock_req == NULL) {
    9408           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    9409           0 :                 return false;
    9410             :         }
    9411           0 :         tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
    9412             : 
    9413             :         /* Get ACL on POSIX connection - should break oplock. */
    9414           0 :         getacl_req = cli_posix_getacl_send(talloc_tos(),
    9415             :                                 ev,
    9416             :                                 cli2,
    9417             :                                 fname);
    9418           0 :         if (getacl_req == NULL) {
    9419           0 :                 printf("cli_posix_getacl_send failed\n");
    9420           0 :                 return false;
    9421             :         }
    9422           0 :         tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
    9423             : 
    9424           0 :         while (!got_break || !acl_ret) {
    9425             :                 int ret;
    9426           0 :                 ret = tevent_loop_once(ev);
    9427           0 :                 if (ret == -1) {
    9428           0 :                         printf("tevent_loop_once failed: %s\n",
    9429           0 :                                strerror(errno));
    9430           0 :                         return false;
    9431             :                 }
    9432             :         }
    9433             : 
    9434           0 :         if (!NT_STATUS_IS_OK(state->status)) {
    9435           0 :                 printf("getacl failed (%s)\n", nt_errstr(state->status));
    9436           0 :                 correct = false;
    9437             :         }
    9438             : 
    9439           0 :         status = cli_close(cli1, fnum);
    9440           0 :         if (!NT_STATUS_IS_OK(status)) {
    9441           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    9442           0 :                 correct = false;
    9443             :         }
    9444             : 
    9445           0 :         status = cli_unlink(cli1,
    9446             :                         fname,
    9447             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9448           0 :         if (!NT_STATUS_IS_OK(status)) {
    9449           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    9450           0 :                 correct = false;
    9451             :         }
    9452             : 
    9453           0 :         if (!torture_close_connection(cli1)) {
    9454           0 :                 correct = false;
    9455             :         }
    9456           0 :         if (!torture_close_connection(cli2)) {
    9457           0 :                 correct = false;
    9458             :         }
    9459             : 
    9460           0 :         if (!got_break) {
    9461           0 :                 correct = false;
    9462             :         }
    9463             : 
    9464           0 :         printf("finished posix acl oplock test\n");
    9465             : 
    9466           0 :         return correct;
    9467             : }
    9468             : 
    9469           0 : static bool run_posix_acl_shareroot_test(int dummy)
    9470             : {
    9471             :         struct cli_state *cli;
    9472             :         NTSTATUS status;
    9473           0 :         bool correct = false;
    9474           0 :         char *posix_acl = NULL;
    9475           0 :         size_t posix_acl_len = 0;
    9476           0 :         uint16_t num_file_acls = 0;
    9477           0 :         uint16_t num_dir_acls = 0;
    9478             :         uint16_t i;
    9479           0 :         uint32_t expected_size = 0;
    9480           0 :         bool got_user = false;
    9481           0 :         bool got_group = false;
    9482           0 :         bool got_other = false;
    9483           0 :         TALLOC_CTX *frame = NULL;
    9484             : 
    9485           0 :         frame = talloc_stackframe();
    9486             : 
    9487           0 :         printf("starting posix_acl_shareroot test\n");
    9488             : 
    9489           0 :         if (!torture_open_connection(&cli, 0)) {
    9490           0 :                 TALLOC_FREE(frame);
    9491           0 :                 return false;
    9492             :         }
    9493             : 
    9494           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9495             : 
    9496           0 :         status = torture_setup_unix_extensions(cli);
    9497           0 :         if (!NT_STATUS_IS_OK(status)) {
    9498           0 :                 printf("Failed to setup unix extensions\n");
    9499           0 :                 goto out;
    9500             :         }
    9501             : 
    9502             :         /* Get the POSIX ACL on the root of the share. */
    9503           0 :         status = cli_posix_getacl(cli,
    9504             :                                 ".",
    9505             :                                 frame,
    9506             :                                 &posix_acl_len,
    9507             :                                 &posix_acl);
    9508             : 
    9509           0 :         if (!NT_STATUS_IS_OK(status)) {
    9510           0 :                 printf("cli_posix_getacl of '.' failed (%s)\n",
    9511             :                         nt_errstr(status));
    9512           0 :                 goto out;
    9513             :         }
    9514             : 
    9515           0 :         if (posix_acl_len < 6 ||
    9516           0 :                         SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
    9517           0 :                 printf("getfacl ., unknown POSIX acl version %u.\n",
    9518           0 :                         (unsigned int)CVAL(posix_acl,0) );
    9519           0 :                 goto out;
    9520             :         }
    9521             : 
    9522           0 :         num_file_acls = SVAL(posix_acl,2);
    9523           0 :         num_dir_acls = SVAL(posix_acl,4);
    9524           0 :         expected_size = SMB_POSIX_ACL_HEADER_SIZE +
    9525           0 :                                 SMB_POSIX_ACL_ENTRY_SIZE*
    9526           0 :                                 (num_file_acls+num_dir_acls);
    9527             : 
    9528           0 :         if (posix_acl_len != expected_size) {
    9529           0 :                 printf("incorrect POSIX acl buffer size "
    9530             :                         "(should be %u, was %u).\n",
    9531             :                         (unsigned int)expected_size,
    9532             :                         (unsigned int)posix_acl_len);
    9533           0 :                 goto out;
    9534             :         }
    9535             : 
    9536             :         /*
    9537             :          * We don't need to know what the ACL's are
    9538             :          * we just need to know we have at least 3
    9539             :          * file entries (u,g,o).
    9540             :          */
    9541             : 
    9542           0 :         for (i = 0; i < num_file_acls; i++) {
    9543           0 :                 unsigned char tagtype =
    9544           0 :                         CVAL(posix_acl,
    9545             :                                 SMB_POSIX_ACL_HEADER_SIZE+
    9546             :                                 (i*SMB_POSIX_ACL_ENTRY_SIZE));
    9547             : 
    9548           0 :                 switch(tagtype) {
    9549           0 :                         case SMB_POSIX_ACL_USER_OBJ:
    9550           0 :                                 got_user = true;
    9551           0 :                                 break;
    9552           0 :                         case SMB_POSIX_ACL_GROUP_OBJ:
    9553           0 :                                 got_group = true;
    9554           0 :                                 break;
    9555           0 :                         case SMB_POSIX_ACL_OTHER:
    9556           0 :                                 got_other = true;
    9557           0 :                                 break;
    9558           0 :                         default:
    9559           0 :                                 break;
    9560             :                 }
    9561             :         }
    9562             : 
    9563           0 :         if (!got_user) {
    9564           0 :                 printf("Missing user entry\n");
    9565           0 :                 goto out;
    9566             :         }
    9567             : 
    9568           0 :         if (!got_group) {
    9569           0 :                 printf("Missing group entry\n");
    9570           0 :                 goto out;
    9571             :         }
    9572             : 
    9573           0 :         if (!got_other) {
    9574           0 :                 printf("Missing other entry\n");
    9575           0 :                 goto out;
    9576             :         }
    9577             : 
    9578           0 :         correct = true;
    9579             : 
    9580           0 :   out:
    9581             : 
    9582           0 :         if (!torture_close_connection(cli)) {
    9583           0 :                 correct = false;
    9584             :         }
    9585             : 
    9586           0 :         printf("finished posix acl shareroot test\n");
    9587           0 :         TALLOC_FREE(frame);
    9588             : 
    9589           0 :         return correct;
    9590             : }
    9591             : 
    9592             : static uint32_t open_attrs_table[] = {
    9593             :                 FILE_ATTRIBUTE_NORMAL,
    9594             :                 FILE_ATTRIBUTE_ARCHIVE,
    9595             :                 FILE_ATTRIBUTE_READONLY,
    9596             :                 FILE_ATTRIBUTE_HIDDEN,
    9597             :                 FILE_ATTRIBUTE_SYSTEM,
    9598             : 
    9599             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
    9600             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
    9601             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
    9602             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9603             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9604             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9605             : 
    9606             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9607             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9608             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9609             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
    9610             : };
    9611             : 
    9612             : struct trunc_open_results {
    9613             :         unsigned int num;
    9614             :         uint32_t init_attr;
    9615             :         uint32_t trunc_attr;
    9616             :         uint32_t result_attr;
    9617             : };
    9618             : 
    9619             : static struct trunc_open_results attr_results[] = {
    9620             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9621             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9622             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9623             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9624             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9625             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9626             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9627             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9628             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9629             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9630             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9631             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9632             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9633             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9634             :         { 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 },
    9635             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9636             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9637             :         { 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 },
    9638             :         { 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 },
    9639             :         { 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 },
    9640             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9641             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9642             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9643             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9644             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9645             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
    9646             : };
    9647             : 
    9648           0 : static bool run_openattrtest(int dummy)
    9649             : {
    9650             :         static struct cli_state *cli1;
    9651           0 :         const char *fname = "\\openattr.file";
    9652             :         uint16_t fnum1;
    9653           0 :         bool correct = True;
    9654             :         uint32_t attr;
    9655             :         unsigned int i, j, k, l;
    9656             :         NTSTATUS status;
    9657             : 
    9658           0 :         printf("starting open attr test\n");
    9659             : 
    9660           0 :         if (!torture_open_connection(&cli1, 0)) {
    9661           0 :                 return False;
    9662             :         }
    9663             : 
    9664           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9665             : 
    9666           0 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
    9667           0 :                 cli_setatr(cli1, fname, 0, 0);
    9668           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9669             : 
    9670           0 :                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
    9671             :                                        open_attrs_table[i], FILE_SHARE_NONE,
    9672             :                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    9673           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9674           0 :                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9675           0 :                         return False;
    9676             :                 }
    9677             : 
    9678           0 :                 status = cli_close(cli1, fnum1);
    9679           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9680           0 :                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9681           0 :                         return False;
    9682             :                 }
    9683             : 
    9684           0 :                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
    9685           0 :                         status = cli_ntcreate(cli1, fname, 0,
    9686             :                                               FILE_READ_DATA|FILE_WRITE_DATA,
    9687             :                                               open_attrs_table[j],
    9688             :                                               FILE_SHARE_NONE, FILE_OVERWRITE,
    9689             :                                               0, 0, &fnum1, NULL);
    9690           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9691           0 :                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9692           0 :                                         if (attr_results[l].num == k) {
    9693           0 :                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
    9694             :                                                                 k, open_attrs_table[i],
    9695             :                                                                 open_attrs_table[j],
    9696             :                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
    9697           0 :                                                 correct = False;
    9698             :                                         }
    9699             :                                 }
    9700             : 
    9701           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    9702           0 :                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
    9703             :                                                         k, open_attrs_table[i], open_attrs_table[j],
    9704             :                                                         nt_errstr(status));
    9705           0 :                                         correct = False;
    9706             :                                 }
    9707             : #if 0
    9708             :                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
    9709             : #endif
    9710           0 :                                 k++;
    9711           0 :                                 continue;
    9712             :                         }
    9713             : 
    9714           0 :                         status = cli_close(cli1, fnum1);
    9715           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9716           0 :                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
    9717           0 :                                 return False;
    9718             :                         }
    9719             : 
    9720           0 :                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
    9721           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9722           0 :                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
    9723           0 :                                 return False;
    9724             :                         }
    9725             : 
    9726             : #if 0
    9727             :                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
    9728             :                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
    9729             : #endif
    9730             : 
    9731           0 :                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9732           0 :                                 if (attr_results[l].num == k) {
    9733           0 :                                         if (attr != attr_results[l].result_attr ||
    9734           0 :                                                         open_attrs_table[i] != attr_results[l].init_attr ||
    9735           0 :                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
    9736           0 :                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
    9737             :                                                 open_attrs_table[i],
    9738             :                                                 open_attrs_table[j],
    9739             :                                                 (unsigned int)attr,
    9740             :                                                 attr_results[l].result_attr);
    9741           0 :                                                 correct = False;
    9742             :                                         }
    9743           0 :                                         break;
    9744             :                                 }
    9745             :                         }
    9746           0 :                         k++;
    9747             :                 }
    9748             :         }
    9749             : 
    9750           0 :         cli_setatr(cli1, fname, 0, 0);
    9751           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9752             : 
    9753           0 :         printf("open attr test %s.\n", correct ? "passed" : "failed");
    9754             : 
    9755           0 :         if (!torture_close_connection(cli1)) {
    9756           0 :                 correct = False;
    9757             :         }
    9758           0 :         return correct;
    9759             : }
    9760             : 
    9761           0 : static NTSTATUS list_fn(struct file_info *finfo,
    9762             :                     const char *name, void *state)
    9763             : {
    9764           0 :         int *matched = (int *)state;
    9765           0 :         if (matched != NULL) {
    9766           0 :                 *matched += 1;
    9767             :         }
    9768           0 :         return NT_STATUS_OK;
    9769             : }
    9770             : 
    9771             : /*
    9772             :   test directory listing speed
    9773             :  */
    9774           1 : static bool run_dirtest(int dummy)
    9775             : {
    9776             :         int i;
    9777             :         static struct cli_state *cli;
    9778             :         uint16_t fnum;
    9779             :         struct timeval core_start;
    9780           1 :         bool correct = True;
    9781             :         int matched;
    9782             : 
    9783           1 :         printf("starting directory test\n");
    9784             : 
    9785           1 :         if (!torture_open_connection(&cli, 0)) {
    9786           0 :                 return False;
    9787             :         }
    9788             : 
    9789           1 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9790             : 
    9791           1 :         srandom(0);
    9792         101 :         for (i=0;i<torture_numops;i++) {
    9793             :                 fstring fname;
    9794         100 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9795         100 :                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
    9796           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
    9797           0 :                         return False;
    9798             :                 }
    9799         100 :                 cli_close(cli, fnum);
    9800             :         }
    9801             : 
    9802           1 :         core_start = timeval_current();
    9803             : 
    9804           1 :         matched = 0;
    9805           1 :         cli_list(cli, "a*.*", 0, list_fn, &matched);
    9806           1 :         printf("Matched %d\n", matched);
    9807             : 
    9808           1 :         matched = 0;
    9809           1 :         cli_list(cli, "b*.*", 0, list_fn, &matched);
    9810           1 :         printf("Matched %d\n", matched);
    9811             : 
    9812           1 :         matched = 0;
    9813           1 :         cli_list(cli, "xyzabc", 0, list_fn, &matched);
    9814           1 :         printf("Matched %d\n", matched);
    9815             : 
    9816           1 :         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
    9817             : 
    9818           1 :         srandom(0);
    9819         101 :         for (i=0;i<torture_numops;i++) {
    9820             :                 fstring fname;
    9821         100 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9822         100 :                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9823             :         }
    9824             : 
    9825           1 :         if (!torture_close_connection(cli)) {
    9826           0 :                 correct = False;
    9827             :         }
    9828             : 
    9829           1 :         printf("finished dirtest\n");
    9830             : 
    9831           1 :         return correct;
    9832             : }
    9833             : 
    9834           0 : static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
    9835             :                    void *state)
    9836             : {
    9837           0 :         struct cli_state *pcli = (struct cli_state *)state;
    9838             :         fstring fname;
    9839           0 :         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
    9840             : 
    9841           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
    9842           0 :                 return NT_STATUS_OK;
    9843             : 
    9844           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    9845           0 :                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
    9846           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
    9847             :         } else {
    9848           0 :                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
    9849           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
    9850             :         }
    9851           0 :         return NT_STATUS_OK;
    9852             : }
    9853             : 
    9854             : 
    9855             : /*
    9856             :   sees what IOCTLs are supported
    9857             :  */
    9858           1 : bool torture_ioctl_test(int dummy)
    9859             : {
    9860             :         static struct cli_state *cli;
    9861             :         uint16_t device, function;
    9862             :         uint16_t fnum;
    9863           1 :         const char *fname = "\\ioctl.dat";
    9864             :         DATA_BLOB blob;
    9865             :         NTSTATUS status;
    9866             : 
    9867           1 :         if (!torture_open_connection(&cli, 0)) {
    9868           0 :                 return False;
    9869             :         }
    9870             : 
    9871           1 :         printf("starting ioctl test\n");
    9872             : 
    9873           1 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9874             : 
    9875           1 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    9876           1 :         if (!NT_STATUS_IS_OK(status)) {
    9877           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9878           0 :                 return False;
    9879             :         }
    9880             : 
    9881           1 :         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
    9882           1 :         printf("ioctl device info: %s\n", nt_errstr(status));
    9883             : 
    9884           1 :         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
    9885           1 :         printf("ioctl job info: %s\n", nt_errstr(status));
    9886             : 
    9887         257 :         for (device=0;device<0x100;device++) {
    9888         256 :                 printf("ioctl test with device = 0x%x\n", device);
    9889       65792 :                 for (function=0;function<0x100;function++) {
    9890       65536 :                         uint32_t code = (device<<16) | function;
    9891             : 
    9892       65536 :                         status = cli_raw_ioctl(cli, fnum, code, &blob);
    9893             : 
    9894       65536 :                         if (NT_STATUS_IS_OK(status)) {
    9895           0 :                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
    9896           0 :                                        (int)blob.length);
    9897           0 :                                 data_blob_free(&blob);
    9898             :                         }
    9899             :                 }
    9900             :         }
    9901             : 
    9902           1 :         if (!torture_close_connection(cli)) {
    9903           0 :                 return False;
    9904             :         }
    9905             : 
    9906           1 :         return True;
    9907             : }
    9908             : 
    9909             : 
    9910             : /*
    9911             :   tries varients of chkpath
    9912             :  */
    9913           1 : bool torture_chkpath_test(int dummy)
    9914             : {
    9915             :         static struct cli_state *cli;
    9916             :         uint16_t fnum;
    9917             :         bool ret;
    9918             :         NTSTATUS status;
    9919             : 
    9920           1 :         if (!torture_open_connection(&cli, 0)) {
    9921           0 :                 return False;
    9922             :         }
    9923             : 
    9924           1 :         printf("starting chkpath test\n");
    9925             : 
    9926             :         /* cleanup from an old run */
    9927           1 :         torture_deltree(cli, "\\chkpath.dir");
    9928             : 
    9929           1 :         status = cli_mkdir(cli, "\\chkpath.dir");
    9930           1 :         if (!NT_STATUS_IS_OK(status)) {
    9931           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
    9932           0 :                 return False;
    9933             :         }
    9934             : 
    9935           1 :         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
    9936           1 :         if (!NT_STATUS_IS_OK(status)) {
    9937           0 :                 printf("mkdir2 failed : %s\n", nt_errstr(status));
    9938           0 :                 return False;
    9939             :         }
    9940             : 
    9941           1 :         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
    9942             :                           DENY_NONE, &fnum);
    9943           1 :         if (!NT_STATUS_IS_OK(status)) {
    9944           0 :                 printf("open1 failed (%s)\n", nt_errstr(status));
    9945           0 :                 return False;
    9946             :         }
    9947           1 :         cli_close(cli, fnum);
    9948             : 
    9949           1 :         status = cli_chkpath(cli, "\\chkpath.dir");
    9950           1 :         if (!NT_STATUS_IS_OK(status)) {
    9951           0 :                 printf("chkpath1 failed: %s\n", nt_errstr(status));
    9952           0 :                 ret = False;
    9953             :         }
    9954             : 
    9955           1 :         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
    9956           1 :         if (!NT_STATUS_IS_OK(status)) {
    9957           0 :                 printf("chkpath2 failed: %s\n", nt_errstr(status));
    9958           0 :                 ret = False;
    9959             :         }
    9960             : 
    9961           1 :         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
    9962           1 :         if (!NT_STATUS_IS_OK(status)) {
    9963           1 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
    9964           1 :                                   NT_STATUS_NOT_A_DIRECTORY);
    9965             :         } else {
    9966           0 :                 printf("* chkpath on a file should fail\n");
    9967           0 :                 ret = False;
    9968             :         }
    9969             : 
    9970           1 :         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
    9971           1 :         if (!NT_STATUS_IS_OK(status)) {
    9972           1 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
    9973           1 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
    9974             :         } else {
    9975           0 :                 printf("* chkpath on a non existent file should fail\n");
    9976           0 :                 ret = False;
    9977             :         }
    9978             : 
    9979           1 :         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
    9980           1 :         if (!NT_STATUS_IS_OK(status)) {
    9981           1 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
    9982           1 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
    9983             :         } else {
    9984           0 :                 printf("* chkpath on a non existent component should fail\n");
    9985           0 :                 ret = False;
    9986             :         }
    9987             : 
    9988           1 :         torture_deltree(cli, "\\chkpath.dir");
    9989             : 
    9990           1 :         if (!torture_close_connection(cli)) {
    9991           0 :                 return False;
    9992             :         }
    9993             : 
    9994           1 :         return ret;
    9995             : }
    9996             : 
    9997           0 : static bool run_eatest(int dummy)
    9998             : {
    9999             :         static struct cli_state *cli;
   10000           0 :         const char *fname = "\\eatest.txt";
   10001           0 :         bool correct = True;
   10002             :         uint16_t fnum;
   10003             :         size_t i, num_eas;
   10004           0 :         struct ea_struct *ea_list = NULL;
   10005           0 :         TALLOC_CTX *mem_ctx = talloc_init("eatest");
   10006             :         NTSTATUS status;
   10007             : 
   10008           0 :         printf("starting eatest\n");
   10009             : 
   10010           0 :         if (!torture_open_connection(&cli, 0)) {
   10011           0 :                 talloc_destroy(mem_ctx);
   10012           0 :                 return False;
   10013             :         }
   10014             : 
   10015           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10016             : 
   10017           0 :         status = cli_ntcreate(cli, fname, 0,
   10018             :                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10019             :                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
   10020             :                               0x4044, 0, &fnum, NULL);
   10021           0 :         if (!NT_STATUS_IS_OK(status)) {
   10022           0 :                 printf("open failed - %s\n", nt_errstr(status));
   10023           0 :                 talloc_destroy(mem_ctx);
   10024           0 :                 return False;
   10025             :         }
   10026             : 
   10027           0 :         for (i = 0; i < 10; i++) {
   10028             :                 fstring ea_name, ea_val;
   10029             : 
   10030           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
   10031           0 :                 memset(ea_val, (char)i+1, i+1);
   10032           0 :                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
   10033           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10034           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10035             :                                nt_errstr(status));
   10036           0 :                         talloc_destroy(mem_ctx);
   10037           0 :                         return False;
   10038             :                 }
   10039             :         }
   10040             : 
   10041           0 :         cli_close(cli, fnum);
   10042           0 :         for (i = 0; i < 10; i++) {
   10043             :                 fstring ea_name, ea_val;
   10044             : 
   10045           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
   10046           0 :                 memset(ea_val, (char)i+1, i+1);
   10047           0 :                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
   10048           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10049           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10050             :                                nt_errstr(status));
   10051           0 :                         talloc_destroy(mem_ctx);
   10052           0 :                         return False;
   10053             :                 }
   10054             :         }
   10055             : 
   10056           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10057           0 :         if (!NT_STATUS_IS_OK(status)) {
   10058           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10059           0 :                 correct = False;
   10060             :         }
   10061             : 
   10062           0 :         printf("num_eas = %d\n", (int)num_eas);
   10063             : 
   10064           0 :         if (num_eas != 20) {
   10065           0 :                 printf("Should be 20 EA's stored... failing.\n");
   10066           0 :                 correct = False;
   10067             :         }
   10068             : 
   10069           0 :         for (i = 0; i < num_eas; i++) {
   10070           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10071           0 :                 dump_data(0, ea_list[i].value.data,
   10072           0 :                           ea_list[i].value.length);
   10073             :         }
   10074             : 
   10075             :         /* Setting EA's to zero length deletes them. Test this */
   10076           0 :         printf("Now deleting all EA's - case indepenent....\n");
   10077             : 
   10078             : #if 1
   10079           0 :         cli_set_ea_path(cli, fname, "", "", 0);
   10080             : #else
   10081             :         for (i = 0; i < 20; i++) {
   10082             :                 fstring ea_name;
   10083             :                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
   10084             :                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
   10085             :                 if (!NT_STATUS_IS_OK(status)) {
   10086             :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10087             :                                nt_errstr(status));
   10088             :                         talloc_destroy(mem_ctx);
   10089             :                         return False;
   10090             :                 }
   10091             :         }
   10092             : #endif
   10093             : 
   10094           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10095           0 :         if (!NT_STATUS_IS_OK(status)) {
   10096           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10097           0 :                 correct = False;
   10098             :         }
   10099             : 
   10100           0 :         printf("num_eas = %d\n", (int)num_eas);
   10101           0 :         for (i = 0; i < num_eas; i++) {
   10102           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10103           0 :                 dump_data(0, ea_list[i].value.data,
   10104           0 :                           ea_list[i].value.length);
   10105             :         }
   10106             : 
   10107           0 :         if (num_eas != 0) {
   10108           0 :                 printf("deleting EA's failed.\n");
   10109           0 :                 correct = False;
   10110             :         }
   10111             : 
   10112             :         /* Try and delete a non existent EA. */
   10113           0 :         status = cli_set_ea_path(cli, fname, "foo", "", 0);
   10114           0 :         if (!NT_STATUS_IS_OK(status)) {
   10115           0 :                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
   10116             :                        nt_errstr(status));
   10117           0 :                 correct = False;
   10118             :         }
   10119             : 
   10120           0 :         talloc_destroy(mem_ctx);
   10121           0 :         if (!torture_close_connection(cli)) {
   10122           0 :                 correct = False;
   10123             :         }
   10124             : 
   10125           0 :         return correct;
   10126             : }
   10127             : 
   10128           0 : static bool run_dirtest1(int dummy)
   10129             : {
   10130             :         int i;
   10131             :         static struct cli_state *cli;
   10132             :         uint16_t fnum;
   10133             :         int num_seen;
   10134           0 :         bool correct = True;
   10135             : 
   10136           0 :         printf("starting directory test\n");
   10137             : 
   10138           0 :         if (!torture_open_connection(&cli, 0)) {
   10139           0 :                 return False;
   10140             :         }
   10141             : 
   10142           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10143             : 
   10144           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10145           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10146           0 :         cli_rmdir(cli, "\\LISTDIR");
   10147           0 :         cli_mkdir(cli, "\\LISTDIR");
   10148             : 
   10149             :         /* Create 1000 files and 1000 directories. */
   10150           0 :         for (i=0;i<1000;i++) {
   10151             :                 fstring fname;
   10152           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
   10153           0 :                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10154             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
   10155             :                                    0, 0, &fnum, NULL))) {
   10156           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10157           0 :                         return False;
   10158             :                 }
   10159           0 :                 cli_close(cli, fnum);
   10160             :         }
   10161           0 :         for (i=0;i<1000;i++) {
   10162             :                 fstring fname;
   10163           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
   10164           0 :                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
   10165           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10166           0 :                         return False;
   10167             :                 }
   10168             :         }
   10169             : 
   10170             :         /* Now ensure that doing an old list sees both files and directories. */
   10171           0 :         num_seen = 0;
   10172           0 :         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10173           0 :         printf("num_seen = %d\n", num_seen );
   10174             :         /* We should see 100 files + 1000 directories + . and .. */
   10175           0 :         if (num_seen != 2002)
   10176           0 :                 correct = False;
   10177             : 
   10178             :         /* Ensure if we have the "must have" bits we only see the
   10179             :          * relevent entries.
   10180             :          */
   10181           0 :         num_seen = 0;
   10182           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10183           0 :         printf("num_seen = %d\n", num_seen );
   10184           0 :         if (num_seen != 1002)
   10185           0 :                 correct = False;
   10186             : 
   10187           0 :         num_seen = 0;
   10188           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10189           0 :         printf("num_seen = %d\n", num_seen );
   10190           0 :         if (num_seen != 1000)
   10191           0 :                 correct = False;
   10192             : 
   10193             :         /* Delete everything. */
   10194           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10195           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10196           0 :         cli_rmdir(cli, "\\LISTDIR");
   10197             : 
   10198             : #if 0
   10199             :         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
   10200             :         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
   10201             :         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
   10202             : #endif
   10203             : 
   10204           0 :         if (!torture_close_connection(cli)) {
   10205           0 :                 correct = False;
   10206             :         }
   10207             : 
   10208           0 :         printf("finished dirtest1\n");
   10209             : 
   10210           0 :         return correct;
   10211             : }
   10212             : 
   10213           0 : static bool run_error_map_extract(int dummy) {
   10214             : 
   10215             :         static struct cli_state *c_dos;
   10216             :         static struct cli_state *c_nt;
   10217             :         NTSTATUS status;
   10218             : 
   10219             :         uint32_t error;
   10220             : 
   10221             :         uint32_t errnum;
   10222             :         uint8_t errclass;
   10223             : 
   10224             :         NTSTATUS nt_status;
   10225             : 
   10226             :         fstring user;
   10227             : 
   10228             :         /* NT-Error connection */
   10229             : 
   10230           0 :         disable_spnego = true;
   10231           0 :         if (!(c_nt = open_nbt_connection())) {
   10232           0 :                 disable_spnego = false;
   10233           0 :                 return False;
   10234             :         }
   10235           0 :         disable_spnego = false;
   10236             : 
   10237           0 :         status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
   10238             :                                  PROTOCOL_NT1);
   10239             : 
   10240           0 :         if (!NT_STATUS_IS_OK(status)) {
   10241           0 :                 printf("%s rejected the NT-error negprot (%s)\n", host,
   10242             :                        nt_errstr(status));
   10243           0 :                 cli_shutdown(c_nt);
   10244           0 :                 return False;
   10245             :         }
   10246             : 
   10247           0 :         status = cli_session_setup_anon(c_nt);
   10248           0 :         if (!NT_STATUS_IS_OK(status)) {
   10249           0 :                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
   10250           0 :                 return False;
   10251             :         }
   10252             : 
   10253             :         /* DOS-Error connection */
   10254             : 
   10255           0 :         disable_spnego = true;
   10256           0 :         force_dos_errors = true;
   10257           0 :         if (!(c_dos = open_nbt_connection())) {
   10258           0 :                 disable_spnego = false;
   10259           0 :                 force_dos_errors = false;
   10260           0 :                 return False;
   10261             :         }
   10262           0 :         disable_spnego = false;
   10263           0 :         force_dos_errors = false;
   10264             : 
   10265           0 :         status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
   10266             :                                  PROTOCOL_NT1);
   10267           0 :         if (!NT_STATUS_IS_OK(status)) {
   10268           0 :                 printf("%s rejected the DOS-error negprot (%s)\n", host,
   10269             :                        nt_errstr(status));
   10270           0 :                 cli_shutdown(c_dos);
   10271           0 :                 return False;
   10272             :         }
   10273             : 
   10274           0 :         status = cli_session_setup_anon(c_dos);
   10275           0 :         if (!NT_STATUS_IS_OK(status)) {
   10276           0 :                 printf("%s rejected the DOS-error initial session setup (%s)\n",
   10277             :                         host, nt_errstr(status));
   10278           0 :                 return False;
   10279             :         }
   10280             : 
   10281           0 :         c_nt->map_dos_errors = false;
   10282           0 :         c_dos->map_dos_errors = false;
   10283             : 
   10284           0 :         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
   10285           0 :                 struct cli_credentials *user_creds = NULL;
   10286             : 
   10287           0 :                 fstr_sprintf(user, "%X", error);
   10288             : 
   10289           0 :                 user_creds = cli_session_creds_init(talloc_tos(),
   10290             :                                                     user,
   10291             :                                                     workgroup,
   10292             :                                                     NULL, /* realm */
   10293             :                                                     password,
   10294             :                                                     false, /* use_kerberos */
   10295             :                                                     false, /* fallback_after_kerberos */
   10296             :                                                     false, /* use_ccache */
   10297             :                                                     false); /* password_is_nt_hash */
   10298           0 :                 if (user_creds == NULL) {
   10299           0 :                         printf("cli_session_creds_init(%s) failed\n", user);
   10300           0 :                         return false;
   10301             :                 }
   10302             : 
   10303           0 :                 status = cli_session_setup_creds(c_nt, user_creds);
   10304           0 :                 if (NT_STATUS_IS_OK(status)) {
   10305           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10306             :                 }
   10307             : 
   10308             :                 /* Case #1: 32-bit NT errors */
   10309           0 :                 if (!NT_STATUS_IS_DOS(status)) {
   10310           0 :                         nt_status = status;
   10311             :                 } else {
   10312           0 :                         printf("/** Dos error on NT connection! (%s) */\n", 
   10313             :                                nt_errstr(status));
   10314           0 :                         nt_status = NT_STATUS(0xc0000000);
   10315             :                 }
   10316             : 
   10317           0 :                 status = cli_session_setup_creds(c_dos, user_creds);
   10318           0 :                 if (NT_STATUS_IS_OK(status)) {
   10319           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10320             :                 }
   10321             : 
   10322             :                 /* Case #1: 32-bit NT errors */
   10323           0 :                 if (NT_STATUS_IS_DOS(status)) {
   10324           0 :                         printf("/** NT error on DOS connection! (%s) */\n", 
   10325             :                                nt_errstr(status));
   10326           0 :                         errnum = errclass = 0;
   10327             :                 } else {
   10328           0 :                         errclass = NT_STATUS_DOS_CLASS(status);
   10329           0 :                         errnum = NT_STATUS_DOS_CODE(status);
   10330             :                 }
   10331             : 
   10332           0 :                 if (NT_STATUS_V(nt_status) != error) { 
   10333           0 :                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
   10334           0 :                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
   10335           0 :                                get_nt_error_c_code(talloc_tos(), nt_status));
   10336             :                 }
   10337             : 
   10338           0 :                 printf("\t{%s,\t%s,\t%s},\n", 
   10339             :                        smb_dos_err_class(errclass), 
   10340             :                        smb_dos_err_name(errclass, errnum), 
   10341           0 :                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
   10342             : 
   10343           0 :                 TALLOC_FREE(user_creds);
   10344             :         }
   10345           0 :         return True;
   10346             : }
   10347             : 
   10348           0 : static bool run_sesssetup_bench(int dummy)
   10349             : {
   10350             :         static struct cli_state *c;
   10351           0 :         const char *fname = "\\file.dat";
   10352             :         uint16_t fnum;
   10353             :         NTSTATUS status;
   10354             :         int i;
   10355             : 
   10356           0 :         if (!torture_open_connection(&c, 0)) {
   10357           0 :                 return false;
   10358             :         }
   10359             : 
   10360           0 :         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10361             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10362             :                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
   10363           0 :         if (!NT_STATUS_IS_OK(status)) {
   10364           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10365           0 :                 return false;
   10366             :         }
   10367             : 
   10368           0 :         for (i=0; i<torture_numops; i++) {
   10369           0 :                 status = cli_session_setup_creds(c, torture_creds);
   10370           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10371           0 :                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
   10372             :                                  __location__, nt_errstr(status));
   10373           0 :                         return false;
   10374             :                 }
   10375             : 
   10376           0 :                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
   10377             : 
   10378           0 :                 status = cli_ulogoff(c);
   10379           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10380           0 :                         d_printf("(%s) cli_ulogoff failed: %s\n",
   10381             :                                  __location__, nt_errstr(status));
   10382           0 :                         return false;
   10383             :                 }
   10384             :         }
   10385             : 
   10386           0 :         return true;
   10387             : }
   10388             : 
   10389           0 : static bool subst_test(const char *str, const char *user, const char *domain,
   10390             :                        uid_t uid, gid_t gid, const char *expected)
   10391             : {
   10392             :         char *subst;
   10393           0 :         bool result = true;
   10394             : 
   10395           0 :         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
   10396             : 
   10397           0 :         if (strcmp(subst, expected) != 0) {
   10398           0 :                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
   10399             :                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
   10400             :                        expected);
   10401           0 :                 result = false;
   10402             :         }
   10403             : 
   10404           0 :         TALLOC_FREE(subst);
   10405           0 :         return result;
   10406             : }
   10407             : 
   10408           1 : static void chain1_open_completion(struct tevent_req *req)
   10409             : {
   10410             :         uint16_t fnum;
   10411             :         NTSTATUS status;
   10412           1 :         status = cli_openx_recv(req, &fnum);
   10413           1 :         TALLOC_FREE(req);
   10414             : 
   10415           1 :         d_printf("cli_openx_recv returned %s: %d\n",
   10416             :                  nt_errstr(status),
   10417           1 :                  NT_STATUS_IS_OK(status) ? fnum : -1);
   10418           1 : }
   10419             : 
   10420           1 : static void chain1_write_completion(struct tevent_req *req)
   10421             : {
   10422             :         size_t written;
   10423             :         NTSTATUS status;
   10424           1 :         status = cli_write_andx_recv(req, &written);
   10425           1 :         TALLOC_FREE(req);
   10426             : 
   10427           2 :         d_printf("cli_write_andx_recv returned %s: %d\n",
   10428             :                  nt_errstr(status),
   10429           2 :                  NT_STATUS_IS_OK(status) ? (int)written : -1);
   10430           1 : }
   10431             : 
   10432           1 : static void chain1_close_completion(struct tevent_req *req)
   10433             : {
   10434             :         NTSTATUS status;
   10435           1 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10436             : 
   10437           1 :         status = cli_close_recv(req);
   10438           1 :         *done = true;
   10439             : 
   10440           1 :         TALLOC_FREE(req);
   10441             : 
   10442           1 :         d_printf("cli_close returned %s\n", nt_errstr(status));
   10443           1 : }
   10444             : 
   10445           1 : static bool run_chain1(int dummy)
   10446             : {
   10447             :         struct cli_state *cli1;
   10448           1 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10449             :         struct tevent_req *reqs[3], *smbreqs[3];
   10450           1 :         bool done = false;
   10451           1 :         const char *str = "foobar";
   10452           1 :         const char *fname = "\\test_chain";
   10453             :         NTSTATUS status;
   10454             : 
   10455           1 :         printf("starting chain1 test\n");
   10456           1 :         if (!torture_open_connection(&cli1, 0)) {
   10457           0 :                 return False;
   10458             :         }
   10459             : 
   10460           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10461             : 
   10462           1 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10463             : 
   10464           1 :         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
   10465             :                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
   10466           1 :         if (reqs[0] == NULL) return false;
   10467           1 :         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
   10468             : 
   10469             : 
   10470           1 :         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
   10471           1 :                                         (const uint8_t *)str, 0, strlen(str)+1,
   10472             :                                         smbreqs, 1, &smbreqs[1]);
   10473           1 :         if (reqs[1] == NULL) return false;
   10474           1 :         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
   10475             : 
   10476           1 :         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
   10477           1 :         if (reqs[2] == NULL) return false;
   10478           1 :         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
   10479             : 
   10480           1 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10481           1 :         if (!NT_STATUS_IS_OK(status)) {
   10482           0 :                 return false;
   10483             :         }
   10484             : 
   10485           8 :         while (!done) {
   10486           6 :                 tevent_loop_once(evt);
   10487             :         }
   10488             : 
   10489           1 :         torture_close_connection(cli1);
   10490           1 :         return True;
   10491             : }
   10492             : 
   10493           1 : static void chain2_sesssetup_completion(struct tevent_req *req)
   10494             : {
   10495             :         NTSTATUS status;
   10496           1 :         status = cli_session_setup_guest_recv(req);
   10497           1 :         d_printf("sesssetup returned %s\n", nt_errstr(status));
   10498           1 : }
   10499             : 
   10500           1 : static void chain2_tcon_completion(struct tevent_req *req)
   10501             : {
   10502           1 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10503             :         NTSTATUS status;
   10504           1 :         status = cli_tcon_andx_recv(req);
   10505           1 :         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
   10506           1 :         *done = true;
   10507           1 : }
   10508             : 
   10509           1 : static bool run_chain2(int dummy)
   10510             : {
   10511             :         struct cli_state *cli1;
   10512           1 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10513             :         struct tevent_req *reqs[2], *smbreqs[2];
   10514           1 :         bool done = false;
   10515             :         NTSTATUS status;
   10516           1 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
   10517             : 
   10518           1 :         printf("starting chain2 test\n");
   10519           1 :         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
   10520             :                                       port_to_use, SMB_SIGNING_DEFAULT, flags);
   10521           1 :         if (!NT_STATUS_IS_OK(status)) {
   10522           0 :                 return False;
   10523             :         }
   10524             : 
   10525           1 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10526             : 
   10527           1 :         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
   10528             :                                                  &smbreqs[0]);
   10529           1 :         if (reqs[0] == NULL) return false;
   10530           1 :         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
   10531             : 
   10532           1 :         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
   10533             :                                        "?????", NULL, 0, &smbreqs[1]);
   10534           1 :         if (reqs[1] == NULL) return false;
   10535           1 :         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
   10536             : 
   10537           1 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10538           1 :         if (!NT_STATUS_IS_OK(status)) {
   10539           0 :                 return false;
   10540             :         }
   10541             : 
   10542           7 :         while (!done) {
   10543           5 :                 tevent_loop_once(evt);
   10544             :         }
   10545             : 
   10546           1 :         torture_close_connection(cli1);
   10547           1 :         return True;
   10548             : }
   10549             : 
   10550             : 
   10551             : struct torture_createdel_state {
   10552             :         struct tevent_context *ev;
   10553             :         struct cli_state *cli;
   10554             : };
   10555             : 
   10556             : static void torture_createdel_created(struct tevent_req *subreq);
   10557             : static void torture_createdel_closed(struct tevent_req *subreq);
   10558             : 
   10559           0 : static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
   10560             :                                                  struct tevent_context *ev,
   10561             :                                                  struct cli_state *cli,
   10562             :                                                  const char *name)
   10563             : {
   10564             :         struct tevent_req *req, *subreq;
   10565             :         struct torture_createdel_state *state;
   10566             : 
   10567           0 :         req = tevent_req_create(mem_ctx, &state,
   10568             :                                 struct torture_createdel_state);
   10569           0 :         if (req == NULL) {
   10570           0 :                 return NULL;
   10571             :         }
   10572           0 :         state->ev = ev;
   10573           0 :         state->cli = cli;
   10574             : 
   10575           0 :         subreq = cli_ntcreate_send(
   10576             :                 state, ev, cli, name, 0,
   10577             :                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
   10578             :                 FILE_ATTRIBUTE_NORMAL,
   10579             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   10580             :                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
   10581             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
   10582             : 
   10583           0 :         if (tevent_req_nomem(subreq, req)) {
   10584           0 :                 return tevent_req_post(req, ev);
   10585             :         }
   10586           0 :         tevent_req_set_callback(subreq, torture_createdel_created, req);
   10587           0 :         return req;
   10588             : }
   10589             : 
   10590           0 : static void torture_createdel_created(struct tevent_req *subreq)
   10591             : {
   10592           0 :         struct tevent_req *req = tevent_req_callback_data(
   10593             :                 subreq, struct tevent_req);
   10594           0 :         struct torture_createdel_state *state = tevent_req_data(
   10595             :                 req, struct torture_createdel_state);
   10596             :         NTSTATUS status;
   10597             :         uint16_t fnum;
   10598             : 
   10599           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
   10600           0 :         TALLOC_FREE(subreq);
   10601           0 :         if (tevent_req_nterror(req, status)) {
   10602           0 :                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
   10603             :                            nt_errstr(status)));
   10604           0 :                 return;
   10605             :         }
   10606             : 
   10607           0 :         subreq = cli_close_send(state, state->ev, state->cli, fnum);
   10608           0 :         if (tevent_req_nomem(subreq, req)) {
   10609           0 :                 return;
   10610             :         }
   10611           0 :         tevent_req_set_callback(subreq, torture_createdel_closed, req);
   10612             : }
   10613             : 
   10614           0 : static void torture_createdel_closed(struct tevent_req *subreq)
   10615             : {
   10616           0 :         struct tevent_req *req = tevent_req_callback_data(
   10617             :                 subreq, struct tevent_req);
   10618             :         NTSTATUS status;
   10619             : 
   10620           0 :         status = cli_close_recv(subreq);
   10621           0 :         if (tevent_req_nterror(req, status)) {
   10622           0 :                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
   10623           0 :                 return;
   10624             :         }
   10625           0 :         tevent_req_done(req);
   10626             : }
   10627             : 
   10628           0 : static NTSTATUS torture_createdel_recv(struct tevent_req *req)
   10629             : {
   10630           0 :         return tevent_req_simple_recv_ntstatus(req);
   10631             : }
   10632             : 
   10633             : struct torture_createdels_state {
   10634             :         struct tevent_context *ev;
   10635             :         struct cli_state *cli;
   10636             :         const char *base_name;
   10637             :         int sent;
   10638             :         int received;
   10639             :         int num_files;
   10640             :         struct tevent_req **reqs;
   10641             : };
   10642             : 
   10643             : static void torture_createdels_done(struct tevent_req *subreq);
   10644             : 
   10645           0 : static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
   10646             :                                                   struct tevent_context *ev,
   10647             :                                                   struct cli_state *cli,
   10648             :                                                   const char *base_name,
   10649             :                                                   int num_parallel,
   10650             :                                                   int num_files)
   10651             : {
   10652             :         struct tevent_req *req;
   10653             :         struct torture_createdels_state *state;
   10654             :         int i;
   10655             : 
   10656           0 :         req = tevent_req_create(mem_ctx, &state,
   10657             :                                 struct torture_createdels_state);
   10658           0 :         if (req == NULL) {
   10659           0 :                 return NULL;
   10660             :         }
   10661           0 :         state->ev = ev;
   10662           0 :         state->cli = cli;
   10663           0 :         state->base_name = talloc_strdup(state, base_name);
   10664           0 :         if (tevent_req_nomem(state->base_name, req)) {
   10665           0 :                 return tevent_req_post(req, ev);
   10666             :         }
   10667           0 :         state->num_files = MAX(num_parallel, num_files);
   10668           0 :         state->sent = 0;
   10669           0 :         state->received = 0;
   10670             : 
   10671           0 :         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
   10672           0 :         if (tevent_req_nomem(state->reqs, req)) {
   10673           0 :                 return tevent_req_post(req, ev);
   10674             :         }
   10675             : 
   10676           0 :         for (i=0; i<num_parallel; i++) {
   10677             :                 char *name;
   10678             : 
   10679           0 :                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10680           0 :                                        state->sent);
   10681           0 :                 if (tevent_req_nomem(name, req)) {
   10682           0 :                         return tevent_req_post(req, ev);
   10683             :                 }
   10684           0 :                 state->reqs[i] = torture_createdel_send(
   10685           0 :                         state->reqs, state->ev, state->cli, name);
   10686           0 :                 if (tevent_req_nomem(state->reqs[i], req)) {
   10687           0 :                         return tevent_req_post(req, ev);
   10688             :                 }
   10689           0 :                 name = talloc_move(state->reqs[i], &name);
   10690           0 :                 tevent_req_set_callback(state->reqs[i],
   10691             :                                         torture_createdels_done, req);
   10692           0 :                 state->sent += 1;
   10693             :         }
   10694           0 :         return req;
   10695             : }
   10696             : 
   10697           0 : static void torture_createdels_done(struct tevent_req *subreq)
   10698             : {
   10699           0 :         struct tevent_req *req = tevent_req_callback_data(
   10700             :                 subreq, struct tevent_req);
   10701           0 :         struct torture_createdels_state *state = tevent_req_data(
   10702             :                 req, struct torture_createdels_state);
   10703           0 :         size_t i, num_parallel = talloc_array_length(state->reqs);
   10704             :         NTSTATUS status;
   10705             :         char *name;
   10706             : 
   10707           0 :         status = torture_createdel_recv(subreq);
   10708           0 :         if (!NT_STATUS_IS_OK(status)){
   10709           0 :                 DEBUG(10, ("torture_createdel_recv returned %s\n",
   10710             :                            nt_errstr(status)));
   10711           0 :                 TALLOC_FREE(subreq);
   10712           0 :                 tevent_req_nterror(req, status);
   10713           0 :                 return;
   10714             :         }
   10715             : 
   10716           0 :         for (i=0; i<num_parallel; i++) {
   10717           0 :                 if (subreq == state->reqs[i]) {
   10718           0 :                         break;
   10719             :                 }
   10720             :         }
   10721           0 :         if (i == num_parallel) {
   10722           0 :                 DEBUG(10, ("received something we did not send\n"));
   10723           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
   10724           0 :                 return;
   10725             :         }
   10726           0 :         TALLOC_FREE(state->reqs[i]);
   10727             : 
   10728           0 :         if (state->sent >= state->num_files) {
   10729           0 :                 tevent_req_done(req);
   10730           0 :                 return;
   10731             :         }
   10732             : 
   10733           0 :         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10734             :                                state->sent);
   10735           0 :         if (tevent_req_nomem(name, req)) {
   10736           0 :                 return;
   10737             :         }
   10738           0 :         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
   10739             :                                                 state->cli, name);
   10740           0 :         if (tevent_req_nomem(state->reqs[i], req)) {
   10741           0 :                 return;
   10742             :         }
   10743           0 :         name = talloc_move(state->reqs[i], &name);
   10744           0 :         tevent_req_set_callback(state->reqs[i],      torture_createdels_done, req);
   10745           0 :         state->sent += 1;
   10746             : }
   10747             : 
   10748           0 : static NTSTATUS torture_createdels_recv(struct tevent_req *req)
   10749             : {
   10750           0 :         return tevent_req_simple_recv_ntstatus(req);
   10751             : }
   10752             : 
   10753             : struct swallow_notify_state {
   10754             :         struct tevent_context *ev;
   10755             :         struct cli_state *cli;
   10756             :         uint16_t fnum;
   10757             :         uint32_t completion_filter;
   10758             :         bool recursive;
   10759             :         bool (*fn)(uint32_t action, const char *name, void *priv);
   10760             :         void *priv;
   10761             : };
   10762             : 
   10763             : static void swallow_notify_done(struct tevent_req *subreq);
   10764             : 
   10765           0 : static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
   10766             :                                               struct tevent_context *ev,
   10767             :                                               struct cli_state *cli,
   10768             :                                               uint16_t fnum,
   10769             :                                               uint32_t completion_filter,
   10770             :                                               bool recursive,
   10771             :                                               bool (*fn)(uint32_t action,
   10772             :                                                          const char *name,
   10773             :                                                          void *priv),
   10774             :                                               void *priv)
   10775             : {
   10776             :         struct tevent_req *req, *subreq;
   10777             :         struct swallow_notify_state *state;
   10778             : 
   10779           0 :         req = tevent_req_create(mem_ctx, &state,
   10780             :                                 struct swallow_notify_state);
   10781           0 :         if (req == NULL) {
   10782           0 :                 return NULL;
   10783             :         }
   10784           0 :         state->ev = ev;
   10785           0 :         state->cli = cli;
   10786           0 :         state->fnum = fnum;
   10787           0 :         state->completion_filter = completion_filter;
   10788           0 :         state->recursive = recursive;
   10789           0 :         state->fn = fn;
   10790           0 :         state->priv = priv;
   10791             : 
   10792           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10793           0 :                                  0xffff, state->completion_filter,
   10794           0 :                                  state->recursive);
   10795           0 :         if (tevent_req_nomem(subreq, req)) {
   10796           0 :                 return tevent_req_post(req, ev);
   10797             :         }
   10798           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10799           0 :         return req;
   10800             : }
   10801             : 
   10802           0 : static void swallow_notify_done(struct tevent_req *subreq)
   10803             : {
   10804           0 :         struct tevent_req *req = tevent_req_callback_data(
   10805             :                 subreq, struct tevent_req);
   10806           0 :         struct swallow_notify_state *state = tevent_req_data(
   10807             :                 req, struct swallow_notify_state);
   10808             :         NTSTATUS status;
   10809             :         uint32_t i, num_changes;
   10810             :         struct notify_change *changes;
   10811             : 
   10812           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
   10813           0 :         TALLOC_FREE(subreq);
   10814           0 :         if (!NT_STATUS_IS_OK(status)) {
   10815           0 :                 DEBUG(10, ("cli_notify_recv returned %s\n",
   10816             :                            nt_errstr(status)));
   10817           0 :                 tevent_req_nterror(req, status);
   10818           0 :                 return;
   10819             :         }
   10820             : 
   10821           0 :         for (i=0; i<num_changes; i++) {
   10822           0 :                 state->fn(changes[i].action, changes[i].name, state->priv);
   10823             :         }
   10824           0 :         TALLOC_FREE(changes);
   10825             : 
   10826           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10827             :                                  0xffff, state->completion_filter,
   10828           0 :                                  state->recursive);
   10829           0 :         if (tevent_req_nomem(subreq, req)) {
   10830           0 :                 return;
   10831             :         }
   10832           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10833             : }
   10834             : 
   10835           0 : static bool print_notifies(uint32_t action, const char *name, void *priv)
   10836             : {
   10837           0 :         if (DEBUGLEVEL > 5) {
   10838           0 :                 d_printf("%d %s\n", (int)action, name);
   10839             :         }
   10840           0 :         return true;
   10841             : }
   10842             : 
   10843           0 : static void notify_bench_done(struct tevent_req *req)
   10844             : {
   10845           0 :         int *num_finished = (int *)tevent_req_callback_data_void(req);
   10846           0 :         *num_finished += 1;
   10847           0 : }
   10848             : 
   10849           0 : static bool run_notify_bench(int dummy)
   10850             : {
   10851           0 :         const char *dname = "\\notify-bench";
   10852             :         struct tevent_context *ev;
   10853             :         NTSTATUS status;
   10854             :         uint16_t dnum;
   10855             :         struct tevent_req *req1;
   10856           0 :         struct tevent_req *req2 = NULL;
   10857             :         int i, num_unc_names;
   10858           0 :         int num_finished = 0;
   10859             : 
   10860           0 :         printf("starting notify-bench test\n");
   10861             : 
   10862           0 :         if (use_multishare_conn) {
   10863             :                 char **unc_list;
   10864           0 :                 unc_list = file_lines_load(multishare_conn_fname,
   10865             :                                            &num_unc_names, 0, NULL);
   10866           0 :                 if (!unc_list || num_unc_names <= 0) {
   10867           0 :                         d_printf("Failed to load unc names list from '%s'\n",
   10868             :                                  multishare_conn_fname);
   10869           0 :                         return false;
   10870             :                 }
   10871           0 :                 TALLOC_FREE(unc_list);
   10872             :         } else {
   10873           0 :                 num_unc_names = 1;
   10874             :         }
   10875             : 
   10876           0 :         ev = samba_tevent_context_init(talloc_tos());
   10877           0 :         if (ev == NULL) {
   10878           0 :                 d_printf("tevent_context_init failed\n");
   10879           0 :                 return false;
   10880             :         }
   10881             : 
   10882           0 :         for (i=0; i<num_unc_names; i++) {
   10883             :                 struct cli_state *cli;
   10884             :                 char *base_fname;
   10885             : 
   10886           0 :                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
   10887             :                                              dname, i);
   10888           0 :                 if (base_fname == NULL) {
   10889           0 :                         return false;
   10890             :                 }
   10891             : 
   10892           0 :                 if (!torture_open_connection(&cli, i)) {
   10893           0 :                         return false;
   10894             :                 }
   10895             : 
   10896           0 :                 status = cli_ntcreate(cli, dname, 0,
   10897             :                                       MAXIMUM_ALLOWED_ACCESS,
   10898             :                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
   10899             :                                       FILE_SHARE_DELETE,
   10900             :                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
   10901             :                                       &dnum, NULL);
   10902             : 
   10903           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10904           0 :                         d_printf("Could not create %s: %s\n", dname,
   10905             :                                  nt_errstr(status));
   10906           0 :                         return false;
   10907             :                 }
   10908             : 
   10909           0 :                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
   10910             :                                            FILE_NOTIFY_CHANGE_FILE_NAME |
   10911             :                                            FILE_NOTIFY_CHANGE_DIR_NAME |
   10912             :                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
   10913             :                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
   10914             :                                            false, print_notifies, NULL);
   10915           0 :                 if (req1 == NULL) {
   10916           0 :                         d_printf("Could not create notify request\n");
   10917           0 :                         return false;
   10918             :                 }
   10919             : 
   10920           0 :                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
   10921             :                                                base_fname, 10, torture_numops);
   10922           0 :                 if (req2 == NULL) {
   10923           0 :                         d_printf("Could not create createdels request\n");
   10924           0 :                         return false;
   10925             :                 }
   10926           0 :                 TALLOC_FREE(base_fname);
   10927             : 
   10928           0 :                 tevent_req_set_callback(req2, notify_bench_done,
   10929             :                                         &num_finished);
   10930             :         }
   10931             : 
   10932           0 :         while (num_finished < num_unc_names) {
   10933             :                 int ret;
   10934           0 :                 ret = tevent_loop_once(ev);
   10935           0 :                 if (ret != 0) {
   10936           0 :                         d_printf("tevent_loop_once failed\n");
   10937           0 :                         return false;
   10938             :                 }
   10939             :         }
   10940             : 
   10941           0 :         if (!tevent_req_poll(req2, ev)) {
   10942           0 :                 d_printf("tevent_req_poll failed\n");
   10943             :         }
   10944             : 
   10945           0 :         status = torture_createdels_recv(req2);
   10946           0 :         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
   10947             : 
   10948           0 :         return true;
   10949             : }
   10950             : 
   10951           0 : static bool run_mangle1(int dummy)
   10952             : {
   10953             :         struct cli_state *cli;
   10954           0 :         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
   10955             :         uint16_t fnum;
   10956             :         fstring alt_name;
   10957             :         NTSTATUS status;
   10958             :         time_t change_time, access_time, write_time;
   10959             :         off_t size;
   10960             :         uint32_t attr;
   10961             : 
   10962           0 :         printf("starting mangle1 test\n");
   10963           0 :         if (!torture_open_connection(&cli, 0)) {
   10964           0 :                 return False;
   10965             :         }
   10966             : 
   10967           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10968             : 
   10969           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10970             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10971             :                               0, 0, &fnum, NULL);
   10972           0 :         if (!NT_STATUS_IS_OK(status)) {
   10973           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10974           0 :                 return false;
   10975             :         }
   10976           0 :         cli_close(cli, fnum);
   10977             : 
   10978           0 :         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
   10979           0 :         if (!NT_STATUS_IS_OK(status)) {
   10980           0 :                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
   10981             :                          nt_errstr(status));
   10982           0 :                 return false;
   10983             :         }
   10984           0 :         d_printf("alt_name: %s\n", alt_name);
   10985             : 
   10986           0 :         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
   10987           0 :         if (!NT_STATUS_IS_OK(status)) {
   10988           0 :                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
   10989             :                          nt_errstr(status));
   10990           0 :                 return false;
   10991             :         }
   10992           0 :         cli_close(cli, fnum);
   10993             : 
   10994           0 :         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
   10995             :                                 &write_time, &size, &attr);
   10996           0 :         if (!NT_STATUS_IS_OK(status)) {
   10997           0 :                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
   10998             :                          nt_errstr(status));
   10999           0 :                 return false;
   11000             :         }
   11001             : 
   11002           0 :         return true;
   11003             : }
   11004             : 
   11005           0 : static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
   11006             :                                                  const char *mask,
   11007             :                                                  void *state)
   11008             : {
   11009           0 :         if (f->short_name == NULL) {
   11010           0 :                 return NT_STATUS_OK;
   11011             :         }
   11012             : 
   11013           0 :         if (strlen(f->short_name) == 0) {
   11014           0 :                 return NT_STATUS_OK;
   11015             :         }
   11016             : 
   11017           0 :         printf("unexpected shortname: %s\n", f->short_name);
   11018             : 
   11019           0 :         return NT_STATUS_OBJECT_NAME_INVALID;
   11020             : }
   11021             : 
   11022           0 : static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
   11023             :                                             const char *mask,
   11024             :                                             void *state)
   11025             : {
   11026           0 :         char *name = state;
   11027             : 
   11028           0 :         printf("name: %s\n", f->name);
   11029           0 :         fstrcpy(name, f->name);
   11030           0 :         return NT_STATUS_OK;
   11031             : }
   11032             : 
   11033           0 : static bool run_mangle_illegal(int dummy)
   11034             : {
   11035           0 :         struct cli_state *cli = NULL;
   11036           0 :         struct cli_state *cli_posix = NULL;
   11037           0 :         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
   11038           0 :         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
   11039           0 :         char *mangled_path = NULL;
   11040             :         uint16_t fnum;
   11041             :         fstring name;
   11042             :         fstring alt_name;
   11043             :         NTSTATUS status;
   11044             : 
   11045           0 :         printf("starting mangle-illegal test\n");
   11046             : 
   11047           0 :         if (!torture_open_connection(&cli, 0)) {
   11048           0 :                 return False;
   11049             :         }
   11050             : 
   11051           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11052             : 
   11053           0 :         if (!torture_open_connection(&cli_posix, 0)) {
   11054           0 :                 return false;
   11055             :         }
   11056             : 
   11057           0 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   11058             : 
   11059           0 :         status = torture_setup_unix_extensions(cli_posix);
   11060           0 :         if (!NT_STATUS_IS_OK(status)) {
   11061           0 :                 return false;
   11062             :         }
   11063             : 
   11064           0 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11065           0 :         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
   11066           0 :         if (!NT_STATUS_IS_OK(status)) {
   11067           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   11068           0 :                 return False;
   11069             :         }
   11070             : 
   11071             :         /*
   11072             :          * Create a file with illegal NTFS characters and test that we
   11073             :          * get a usable mangled name
   11074             :          */
   11075             : 
   11076           0 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11077           0 :         cli_posix_unlink(cli_posix, illegal_fname);
   11078             : 
   11079           0 :         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
   11080             :                                 0600, &fnum);
   11081           0 :         if (!NT_STATUS_IS_OK(status)) {
   11082           0 :                 printf("POSIX create of %s failed (%s)\n",
   11083             :                        illegal_fname, nt_errstr(status));
   11084           0 :                 return false;
   11085             :         }
   11086             : 
   11087           0 :         status = cli_close(cli_posix, fnum);
   11088           0 :         if (!NT_STATUS_IS_OK(status)) {
   11089           0 :                 printf("close failed (%s)\n", nt_errstr(status));
   11090           0 :                 return false;
   11091             :         }
   11092             : 
   11093           0 :         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
   11094           0 :         if (!NT_STATUS_IS_OK(status)) {
   11095           0 :                 d_printf("cli_list failed: %s\n", nt_errstr(status));
   11096           0 :                 return false;
   11097             :         }
   11098             : 
   11099           0 :         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
   11100           0 :         if (mangled_path == NULL) {
   11101           0 :                 return false;
   11102             :         }
   11103             : 
   11104           0 :         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
   11105           0 :         if (!NT_STATUS_IS_OK(status)) {
   11106           0 :                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
   11107           0 :                 TALLOC_FREE(mangled_path);
   11108           0 :                 return false;
   11109             :         }
   11110           0 :         TALLOC_FREE(mangled_path);
   11111           0 :         cli_close(cli, fnum);
   11112             : 
   11113           0 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11114           0 :         cli_posix_unlink(cli_posix, illegal_fname);
   11115             : 
   11116             :         /*
   11117             :          * Create a file with a long name and check that we got *no* short name.
   11118             :          */
   11119             : 
   11120           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11121             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11122             :                               0, 0, &fnum, NULL);
   11123           0 :         if (!NT_STATUS_IS_OK(status)) {
   11124           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11125           0 :                 return false;
   11126             :         }
   11127           0 :         cli_close(cli, fnum);
   11128             : 
   11129           0 :         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
   11130           0 :         if (!NT_STATUS_IS_OK(status)) {
   11131           0 :                 d_printf("cli_list failed\n");
   11132           0 :                 return false;
   11133             :         }
   11134             : 
   11135           0 :         cli_unlink(cli, fname, 0);
   11136           0 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11137             : 
   11138           0 :         if (!torture_close_connection(cli_posix)) {
   11139           0 :                 return false;
   11140             :         }
   11141             : 
   11142           0 :         if (!torture_close_connection(cli)) {
   11143           0 :                 return false;
   11144             :         }
   11145             : 
   11146           0 :         return true;
   11147             : }
   11148             : 
   11149           0 : static size_t null_source(uint8_t *buf, size_t n, void *priv)
   11150             : {
   11151           0 :         size_t *to_pull = (size_t *)priv;
   11152           0 :         size_t thistime = *to_pull;
   11153             : 
   11154           0 :         thistime = MIN(thistime, n);
   11155           0 :         if (thistime == 0) {
   11156           0 :                 return 0;
   11157             :         }
   11158             : 
   11159           0 :         memset(buf, 0, thistime);
   11160           0 :         *to_pull -= thistime;
   11161           0 :         return thistime;
   11162             : }
   11163             : 
   11164           0 : static bool run_windows_write(int dummy)
   11165             : {
   11166             :         struct cli_state *cli1;
   11167             :         uint16_t fnum;
   11168             :         int i;
   11169           0 :         bool ret = false;
   11170           0 :         const char *fname = "\\writetest.txt";
   11171             :         struct timeval start_time;
   11172             :         double seconds;
   11173             :         double kbytes;
   11174             :         NTSTATUS status;
   11175             : 
   11176           0 :         printf("starting windows_write test\n");
   11177           0 :         if (!torture_open_connection(&cli1, 0)) {
   11178           0 :                 return False;
   11179             :         }
   11180             : 
   11181           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   11182           0 :         if (!NT_STATUS_IS_OK(status)) {
   11183           0 :                 printf("open failed (%s)\n", nt_errstr(status));
   11184           0 :                 return False;
   11185             :         }
   11186             : 
   11187           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   11188             : 
   11189           0 :         start_time = timeval_current();
   11190             : 
   11191           0 :         for (i=0; i<torture_numops; i++) {
   11192           0 :                 uint8_t c = 0;
   11193           0 :                 off_t start = i * torture_blocksize;
   11194           0 :                 size_t to_pull = torture_blocksize - 1;
   11195             : 
   11196           0 :                 status = cli_writeall(cli1, fnum, 0, &c,
   11197           0 :                                       start + torture_blocksize - 1, 1, NULL);
   11198           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11199           0 :                         printf("cli_write failed: %s\n", nt_errstr(status));
   11200           0 :                         goto fail;
   11201             :                 }
   11202             : 
   11203           0 :                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
   11204             :                                   null_source, &to_pull);
   11205           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11206           0 :                         printf("cli_push returned: %s\n", nt_errstr(status));
   11207           0 :                         goto fail;
   11208             :                 }
   11209             :         }
   11210             : 
   11211           0 :         seconds = timeval_elapsed(&start_time);
   11212           0 :         kbytes = (double)torture_blocksize * torture_numops;
   11213           0 :         kbytes /= 1024;
   11214             : 
   11215           0 :         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
   11216           0 :                (double)seconds, (int)(kbytes/seconds));
   11217             : 
   11218           0 :         ret = true;
   11219           0 :  fail:
   11220           0 :         cli_close(cli1, fnum);
   11221           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11222           0 :         torture_close_connection(cli1);
   11223           0 :         return ret;
   11224             : }
   11225             : 
   11226          16 : static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
   11227             : {
   11228          16 :         size_t max_pdu = 0x1FFFF;
   11229             : 
   11230          16 :         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
   11231           0 :                 max_pdu = 0xFFFFFF;
   11232             :         }
   11233             : 
   11234          16 :         if (smb1cli_conn_signing_is_active(cli->conn)) {
   11235          16 :                 max_pdu = 0x1FFFF;
   11236             :         }
   11237             : 
   11238          16 :         if (smb1cli_conn_encryption_on(cli->conn)) {
   11239           0 :                 max_pdu = CLI_BUFFER_SIZE;
   11240             :         }
   11241             : 
   11242          16 :         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
   11243           2 :                 len_requested &= 0xFFFF;
   11244             :         }
   11245             : 
   11246          16 :         return MIN(len_requested,
   11247             :                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
   11248             : }
   11249             : 
   11250          16 : static bool check_read_call(struct cli_state *cli,
   11251             :                             uint16_t fnum,
   11252             :                             uint8_t *buf,
   11253             :                             size_t len_requested)
   11254             : {
   11255             :         NTSTATUS status;
   11256          16 :         struct tevent_req *subreq = NULL;
   11257          16 :         ssize_t len_read = 0;
   11258          16 :         size_t len_expected = 0;
   11259          16 :         struct tevent_context *ev = NULL;
   11260             : 
   11261          16 :         ev = samba_tevent_context_init(talloc_tos());
   11262          16 :         if (ev == NULL) {
   11263           0 :                 return false;
   11264             :         }
   11265             : 
   11266          16 :         subreq = cli_read_andx_send(talloc_tos(),
   11267             :                                     ev,
   11268             :                                     cli,
   11269             :                                     fnum,
   11270             :                                     0,
   11271             :                                     len_requested);
   11272             : 
   11273          16 :         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
   11274           0 :                 return false;
   11275             :         }
   11276             : 
   11277          16 :         status = cli_read_andx_recv(subreq, &len_read, &buf);
   11278          16 :         if (!NT_STATUS_IS_OK(status)) {
   11279           0 :                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
   11280           0 :                 return false;
   11281             :         }
   11282             : 
   11283          16 :         TALLOC_FREE(subreq);
   11284          16 :         TALLOC_FREE(ev);
   11285             : 
   11286          16 :         len_expected = calc_expected_return(cli, len_requested);
   11287             : 
   11288          16 :         if (len_expected > 0x10000 && len_read == 0x10000) {
   11289             :                 /* Windows servers only return a max of 0x10000,
   11290             :                    doesn't matter if you set CAP_LARGE_READX in
   11291             :                    the client sessionsetupX call or not. */
   11292          12 :                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
   11293             :                         (unsigned int)len_requested);
   11294           4 :         } else if (len_read != len_expected) {
   11295           0 :                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
   11296             :                         (unsigned int)len_requested,
   11297             :                         (unsigned int)len_read,
   11298             :                         (unsigned int)len_expected);
   11299           0 :                 return false;
   11300             :         } else {
   11301           4 :                 d_printf("Correct read reply.\n");
   11302             :         }
   11303             : 
   11304          16 :         return true;
   11305             : }
   11306             : 
   11307             : /* Test large readX variants. */
   11308           2 : static bool large_readx_tests(struct cli_state *cli,
   11309             :                                 uint16_t fnum,
   11310             :                                 uint8_t *buf)
   11311             : {
   11312             :         /* A read of 0xFFFF0001 should *always* return 1 byte. */
   11313           2 :         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
   11314           0 :                 return false;
   11315             :         }
   11316             :         /* A read of 0x10000 should return 0x10000 bytes. */
   11317           2 :         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
   11318           0 :                 return false;
   11319             :         }
   11320             :         /* A read of 0x10000 should return 0x10001 bytes. */
   11321           2 :         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
   11322           0 :                 return false;
   11323             :         }
   11324             :         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
   11325             :            the requested number of bytes. */
   11326           2 :         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
   11327           0 :                 return false;
   11328             :         }
   11329             :         /* A read of 1MB should return 1MB bytes (on Samba). */
   11330           2 :         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
   11331           0 :                 return false;
   11332             :         }
   11333             : 
   11334           2 :         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
   11335           0 :                 return false;
   11336             :         }
   11337           2 :         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
   11338           0 :                 return false;
   11339             :         }
   11340           2 :         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
   11341           0 :                 return false;
   11342             :         }
   11343           2 :         return true;
   11344             : }
   11345             : 
   11346           1 : static bool run_large_readx(int dummy)
   11347             : {
   11348           1 :         uint8_t *buf = NULL;
   11349           1 :         struct cli_state *cli1 = NULL;
   11350           1 :         struct cli_state *cli2 = NULL;
   11351           1 :         bool correct = false;
   11352           1 :         const char *fname = "\\large_readx.dat";
   11353             :         NTSTATUS status;
   11354           1 :         uint16_t fnum1 = UINT16_MAX;
   11355           1 :         uint32_t normal_caps = 0;
   11356           1 :         size_t file_size = 20*1024*1024;
   11357           1 :         TALLOC_CTX *frame = talloc_stackframe();
   11358             :         size_t i;
   11359             :         struct {
   11360             :                 const char *name;
   11361             :                 enum smb_signing_setting signing_setting;
   11362             :                 enum protocol_types protocol;
   11363           1 :         } runs[] = {
   11364             :                 {
   11365             :                         .name = "NT1",
   11366             :                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
   11367             :                         .protocol = PROTOCOL_NT1,
   11368             :                 },{
   11369             :                         .name = "NT1 - SIGNING_REQUIRED",
   11370             :                         .signing_setting = SMB_SIGNING_REQUIRED,
   11371             :                         .protocol = PROTOCOL_NT1,
   11372             :                 },
   11373             :         };
   11374             : 
   11375           1 :         printf("starting large_readx test\n");
   11376             : 
   11377           1 :         if (!torture_open_connection(&cli1, 0)) {
   11378           0 :                 goto out;
   11379             :         }
   11380             : 
   11381           1 :         normal_caps = smb1cli_conn_capabilities(cli1->conn);
   11382             : 
   11383           1 :         if (!(normal_caps & CAP_LARGE_READX)) {
   11384           0 :                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11385             :                         (unsigned int)normal_caps);
   11386           0 :                 goto out;
   11387             :         }
   11388             : 
   11389             :         /* Create a file of size 4MB. */
   11390           1 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
   11391             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11392             :                         0, 0, &fnum1, NULL);
   11393             : 
   11394           1 :         if (!NT_STATUS_IS_OK(status)) {
   11395           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11396           0 :                 goto out;
   11397             :         }
   11398             : 
   11399             :         /* Write file_size bytes. */
   11400           1 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11401           1 :         if (buf == NULL) {
   11402           0 :                 goto out;
   11403             :         }
   11404             : 
   11405           1 :         status = cli_writeall(cli1,
   11406             :                               fnum1,
   11407             :                               0,
   11408             :                               buf,
   11409             :                               0,
   11410             :                               file_size,
   11411             :                               NULL);
   11412           1 :         if (!NT_STATUS_IS_OK(status)) {
   11413           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11414           0 :                 goto out;
   11415             :         }
   11416             : 
   11417           1 :         status = cli_close(cli1, fnum1);
   11418           1 :         if (!NT_STATUS_IS_OK(status)) {
   11419           0 :                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11420           0 :                 goto out;
   11421             :         }
   11422             : 
   11423           1 :         fnum1 = UINT16_MAX;
   11424             : 
   11425           3 :         for (i=0; i < ARRAY_SIZE(runs); i++) {
   11426           2 :                 enum smb_signing_setting saved_signing_setting = signing_state;
   11427           2 :                 uint16_t fnum2 = -1;
   11428             : 
   11429           2 :                 if (do_encrypt &&
   11430           0 :                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
   11431             :                 {
   11432           0 :                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
   11433           0 :                         continue;
   11434             :                 }
   11435             : 
   11436           2 :                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
   11437             : 
   11438           2 :                 signing_state = runs[i].signing_setting;
   11439           2 :                 cli2 = open_nbt_connection();
   11440           2 :                 signing_state = saved_signing_setting;
   11441           2 :                 if (cli2 == NULL) {
   11442           0 :                         goto out;
   11443             :                 }
   11444             : 
   11445           4 :                 status = smbXcli_negprot(cli2->conn,
   11446           2 :                                          cli2->timeout,
   11447             :                                          runs[i].protocol,
   11448             :                                          runs[i].protocol);
   11449           2 :                 if (!NT_STATUS_IS_OK(status)) {
   11450           0 :                         goto out;
   11451             :                 }
   11452             : 
   11453           2 :                 status = cli_session_setup_creds(cli2, torture_creds);
   11454           2 :                 if (!NT_STATUS_IS_OK(status)) {
   11455           0 :                         goto out;
   11456             :                 }
   11457             : 
   11458           2 :                 status = cli_tree_connect(cli2,
   11459             :                                         share,
   11460             :                                         "?????",
   11461             :                                         password);
   11462           2 :                 if (!NT_STATUS_IS_OK(status)) {
   11463           0 :                         goto out;
   11464             :                 }
   11465             : 
   11466           2 :                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
   11467             : 
   11468           2 :                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
   11469             : 
   11470           2 :                 if (!(normal_caps & CAP_LARGE_READX)) {
   11471           0 :                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11472             :                                 (unsigned int)normal_caps);
   11473           0 :                         goto out;
   11474             :                 }
   11475             : 
   11476           2 :                 if (do_encrypt) {
   11477           0 :                         if (force_cli_encryption(cli2, share) == false) {
   11478           0 :                                 goto out;
   11479             :                         }
   11480           2 :                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
   11481             :                         uint16_t major, minor;
   11482             :                         uint32_t caplow, caphigh;
   11483             : 
   11484           0 :                         status = cli_unix_extensions_version(cli2,
   11485             :                                                              &major, &minor,
   11486             :                                                              &caplow, &caphigh);
   11487           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11488           0 :                                 goto out;
   11489             :                         }
   11490             :                 }
   11491             : 
   11492           2 :                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
   11493             :                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
   11494             :                                 0, 0, &fnum2, NULL);
   11495           2 :                 if (!NT_STATUS_IS_OK(status)) {
   11496           0 :                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
   11497           0 :                         goto out;
   11498             :                 }
   11499             : 
   11500             :                 /* All reads must return less than file_size bytes. */
   11501           2 :                 if (!large_readx_tests(cli2, fnum2, buf)) {
   11502           0 :                         goto out;
   11503             :                 }
   11504             : 
   11505           2 :                 status = cli_close(cli2, fnum2);
   11506           2 :                 if (!NT_STATUS_IS_OK(status)) {
   11507           0 :                         d_printf("cli_close failed: %s\n", nt_errstr(status));
   11508           0 :                         goto out;
   11509             :                 }
   11510           2 :                 fnum2 = -1;
   11511             : 
   11512           2 :                 if (!torture_close_connection(cli2)) {
   11513           0 :                         goto out;
   11514             :                 }
   11515           2 :                 cli2 = NULL;
   11516             :         }
   11517             : 
   11518           1 :         correct = true;
   11519           1 :         printf("Success on large_readx test\n");
   11520             : 
   11521           1 :   out:
   11522             : 
   11523           1 :         if (cli2) {
   11524           0 :                 if (!torture_close_connection(cli2)) {
   11525           0 :                         correct = false;
   11526             :                 }
   11527             :         }
   11528             : 
   11529           1 :         if (cli1) {
   11530           1 :                 if (fnum1 != UINT16_MAX) {
   11531           0 :                         status = cli_close(cli1, fnum1);
   11532           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11533           0 :                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11534             :                         }
   11535           0 :                         fnum1 = UINT16_MAX;
   11536             :                 }
   11537             : 
   11538           1 :                 status = cli_unlink(cli1, fname,
   11539             :                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11540           1 :                 if (!NT_STATUS_IS_OK(status)) {
   11541           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
   11542             :                 }
   11543             : 
   11544           1 :                 if (!torture_close_connection(cli1)) {
   11545           0 :                         correct = false;
   11546             :                 }
   11547             :         }
   11548             : 
   11549           1 :         TALLOC_FREE(frame);
   11550             : 
   11551           1 :         printf("finished large_readx test\n");
   11552           1 :         return correct;
   11553             : }
   11554             : 
   11555           0 : static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
   11556             :                                   const char *mask,
   11557             :                                   void *private_data)
   11558             : {
   11559           0 :         uint32_t *p_attr = (uint32_t *)private_data;
   11560             : 
   11561           0 :         if (strequal(finfo->name, test_filename)) {
   11562           0 :                 *p_attr = finfo->attr;
   11563             :         }
   11564             : 
   11565           0 :         return NT_STATUS_OK;
   11566             : }
   11567             : 
   11568           0 : static bool run_msdfs_attribute(int dummy)
   11569             : {
   11570             :         static struct cli_state *cli;
   11571           0 :         bool correct = false;
   11572           0 :         uint32_t attr = 0;
   11573             :         NTSTATUS status;
   11574             : 
   11575           0 :         printf("Starting MSDFS-ATTRIBUTE test\n");
   11576             : 
   11577           0 :         if (test_filename == NULL || test_filename[0] == '\0') {
   11578           0 :                 printf("MSDFS-ATTRIBUTE test "
   11579             :                         "needs -f filename-of-msdfs-link\n");
   11580           0 :                 return false;
   11581             :         }
   11582             : 
   11583             :         /*
   11584             :          * NB. We use torture_open_connection_flags() not
   11585             :          * torture_open_connection() as the latter forces
   11586             :          * SMB1.
   11587             :          */
   11588           0 :         if (!torture_open_connection_flags(&cli, 0, 0)) {
   11589           0 :                 return false;
   11590             :         }
   11591             : 
   11592           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11593             : 
   11594           0 :         status = cli_list(cli,
   11595             :                         "*",
   11596             :                         FILE_ATTRIBUTE_DIRECTORY,
   11597             :                         msdfs_attribute_list_fn,
   11598             :                         &attr);
   11599             : 
   11600           0 :         if (!NT_STATUS_IS_OK(status)) {
   11601           0 :                 printf("cli_list failed with %s\n",
   11602             :                         nt_errstr(status));
   11603           0 :                 goto out;
   11604             :         }
   11605           0 :         if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
   11606           0 :                 printf("file %s should have "
   11607             :                         "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
   11608             :                         test_filename,
   11609             :                         (unsigned int)attr);
   11610           0 :                 goto out;
   11611             :         }
   11612             : 
   11613           0 :         if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
   11614           0 :                 printf("file %s should have "
   11615             :                         "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
   11616             :                         test_filename,
   11617             :                         (unsigned int)attr);
   11618           0 :                 goto out;
   11619             :         }
   11620             : 
   11621           0 :         correct = true;
   11622             : 
   11623           0 :   out:
   11624             : 
   11625           0 :         torture_close_connection(cli);
   11626           0 :         return correct;
   11627             : }
   11628             : 
   11629           0 : static bool run_cli_echo(int dummy)
   11630             : {
   11631             :         struct cli_state *cli;
   11632             :         NTSTATUS status;
   11633             : 
   11634           0 :         printf("starting cli_echo test\n");
   11635           0 :         if (!torture_open_connection(&cli, 0)) {
   11636           0 :                 return false;
   11637             :         }
   11638           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11639             : 
   11640           0 :         status = cli_echo(cli, 5, data_blob_const("hello", 5));
   11641             : 
   11642           0 :         d_printf("cli_echo returned %s\n", nt_errstr(status));
   11643             : 
   11644           0 :         torture_close_connection(cli);
   11645           0 :         return NT_STATUS_IS_OK(status);
   11646             : }
   11647             : 
   11648           2 : static int splice_status(off_t written, void *priv)
   11649             : {
   11650           2 :         return true;
   11651             : }
   11652             : 
   11653           1 : static bool run_cli_splice(int dummy)
   11654             : {
   11655           1 :         uint8_t *buf = NULL;
   11656           1 :         struct cli_state *cli1 = NULL;
   11657           1 :         bool correct = false;
   11658           1 :         const char *fname_src = "\\splice_src.dat";
   11659           1 :         const char *fname_dst = "\\splice_dst.dat";
   11660             :         NTSTATUS status;
   11661           1 :         uint16_t fnum1 = UINT16_MAX;
   11662           1 :         uint16_t fnum2 = UINT16_MAX;
   11663           1 :         size_t file_size = 2*1024*1024;
   11664           1 :         size_t splice_size = 1*1024*1024 + 713;
   11665             :         uint8_t digest1[16], digest2[16];
   11666           1 :         off_t written = 0;
   11667           1 :         size_t nread = 0;
   11668           1 :         TALLOC_CTX *frame = talloc_stackframe();
   11669             : 
   11670           1 :         printf("starting cli_splice test\n");
   11671             : 
   11672           1 :         if (!torture_open_connection(&cli1, 0)) {
   11673           0 :                 goto out;
   11674             :         }
   11675             : 
   11676           1 :         cli_unlink(cli1, fname_src,
   11677             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11678           1 :         cli_unlink(cli1, fname_dst,
   11679             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11680             : 
   11681             :         /* Create a file */
   11682           1 :         status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
   11683             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11684             :                         0, 0, &fnum1, NULL);
   11685             : 
   11686           1 :         if (!NT_STATUS_IS_OK(status)) {
   11687           0 :                 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
   11688           0 :                 goto out;
   11689             :         }
   11690             : 
   11691             :         /* Write file_size bytes - must be bigger than splice_size. */
   11692           1 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11693           1 :         if (buf == NULL) {
   11694           0 :                 d_printf("talloc_fail\n");
   11695           0 :                 goto out;
   11696             :         }
   11697             : 
   11698             :         /* Fill it with random numbers. */
   11699           1 :         generate_random_buffer(buf, file_size);
   11700             : 
   11701             :         /* MD5 the first 1MB + 713 bytes. */
   11702           1 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11703             :                          buf,
   11704             :                          splice_size,
   11705             :                          digest1);
   11706             : 
   11707           1 :         status = cli_writeall(cli1,
   11708             :                               fnum1,
   11709             :                               0,
   11710             :                               buf,
   11711             :                               0,
   11712             :                               file_size,
   11713             :                               NULL);
   11714           1 :         if (!NT_STATUS_IS_OK(status)) {
   11715           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11716           0 :                 goto out;
   11717             :         }
   11718             : 
   11719           1 :         status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
   11720             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11721             :                         0, 0, &fnum2, NULL);
   11722             : 
   11723           1 :         if (!NT_STATUS_IS_OK(status)) {
   11724           0 :                 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
   11725           0 :                 goto out;
   11726             :         }
   11727             : 
   11728             :         /* Now splice 1MB + 713 bytes. */
   11729           1 :         status = cli_splice(cli1,
   11730             :                                 cli1,
   11731             :                                 fnum1,
   11732             :                                 fnum2,
   11733             :                                 splice_size,
   11734             :                                 0,
   11735             :                                 0,
   11736             :                                 &written,
   11737             :                                 splice_status,
   11738             :                                 NULL);
   11739             : 
   11740           1 :         if (!NT_STATUS_IS_OK(status)) {
   11741           0 :                 d_printf("cli_splice failed: %s\n", nt_errstr(status));
   11742           0 :                 goto out;
   11743             :         }
   11744             : 
   11745             :         /* Clear the old buffer. */
   11746           1 :         memset(buf, '\0', file_size);
   11747             : 
   11748             :         /* Read the new file. */
   11749           1 :         status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
   11750           1 :         if (!NT_STATUS_IS_OK(status)) {
   11751           0 :                 d_printf("cli_read failed: %s\n", nt_errstr(status));
   11752           0 :                 goto out;
   11753             :         }
   11754           1 :         if (nread != splice_size) {
   11755           0 :                 d_printf("bad read of 0x%x, should be 0x%x\n",
   11756             :                         (unsigned int)nread,
   11757             :                         (unsigned int)splice_size);
   11758           0 :                 goto out;
   11759             :         }
   11760             : 
   11761             :         /* MD5 the first 1MB + 713 bytes. */
   11762           1 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11763             :                          buf,
   11764             :                          splice_size,
   11765             :                          digest2);
   11766             : 
   11767             :         /* Must be the same. */
   11768           1 :         if (memcmp(digest1, digest2, 16) != 0) {
   11769           0 :                 d_printf("bad MD5 compare\n");
   11770           0 :                 goto out;
   11771             :         }
   11772             : 
   11773           1 :         correct = true;
   11774           1 :         printf("Success on cli_splice test\n");
   11775             : 
   11776           1 :   out:
   11777             : 
   11778           1 :         if (cli1) {
   11779           1 :                 if (fnum1 != UINT16_MAX) {
   11780           1 :                         cli_close(cli1, fnum1);
   11781             :                 }
   11782           1 :                 if (fnum2 != UINT16_MAX) {
   11783           1 :                         cli_close(cli1, fnum2);
   11784             :                 }
   11785             : 
   11786           1 :                 cli_unlink(cli1, fname_src,
   11787             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11788           1 :                 cli_unlink(cli1, fname_dst,
   11789             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11790             : 
   11791           1 :                 if (!torture_close_connection(cli1)) {
   11792           0 :                         correct = false;
   11793             :                 }
   11794             :         }
   11795             : 
   11796           1 :         TALLOC_FREE(frame);
   11797           1 :         return correct;
   11798             : }
   11799             : 
   11800           0 : static bool run_uid_regression_test(int dummy)
   11801             : {
   11802             :         static struct cli_state *cli;
   11803             :         int16_t old_vuid;
   11804             :         int32_t old_cnum;
   11805           0 :         bool correct = True;
   11806           0 :         struct smbXcli_tcon *tcon_copy = NULL;
   11807             :         NTSTATUS status;
   11808             : 
   11809           0 :         printf("starting uid regression test\n");
   11810             : 
   11811           0 :         if (!torture_open_connection(&cli, 0)) {
   11812           0 :                 return False;
   11813             :         }
   11814             : 
   11815           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11816             : 
   11817             :         /* Ok - now save then logoff our current user. */
   11818           0 :         old_vuid = cli_state_get_uid(cli);
   11819             : 
   11820           0 :         status = cli_ulogoff(cli);
   11821           0 :         if (!NT_STATUS_IS_OK(status)) {
   11822           0 :                 d_printf("(%s) cli_ulogoff failed: %s\n",
   11823             :                          __location__, nt_errstr(status));
   11824           0 :                 correct = false;
   11825           0 :                 goto out;
   11826             :         }
   11827             : 
   11828           0 :         cli_state_set_uid(cli, old_vuid);
   11829             : 
   11830             :         /* Try an operation. */
   11831           0 :         status = cli_mkdir(cli, "\\uid_reg_test");
   11832           0 :         if (NT_STATUS_IS_OK(status)) {
   11833           0 :                 d_printf("(%s) cli_mkdir succeeded\n",
   11834             :                          __location__);
   11835           0 :                 correct = false;
   11836           0 :                 goto out;
   11837             :         } else {
   11838             :                 /* Should be bad uid. */
   11839           0 :                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
   11840           0 :                                  NT_STATUS_USER_SESSION_DELETED)) {
   11841           0 :                         correct = false;
   11842           0 :                         goto out;
   11843             :                 }
   11844             :         }
   11845             : 
   11846           0 :         old_cnum = cli_state_get_tid(cli);
   11847             :         /*
   11848             :          * This is an SMB1-only test.
   11849             :          * Copy the tcon, not "save/restore".
   11850             :          *
   11851             :          * In SMB1 the cli_tdis() below frees
   11852             :          * cli->smb1.tcon so we need a copy
   11853             :          * of the struct to put back for the
   11854             :          * second tdis call with invalid vuid.
   11855             :          *
   11856             :          * This is a test-only hack. Real client code
   11857             :          * uses cli_state_save_tcon()/cli_state_restore_tcon().
   11858             :          */
   11859           0 :         tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
   11860           0 :         if (tcon_copy == NULL) {
   11861           0 :                 correct = false;
   11862           0 :                 goto out;
   11863             :         }
   11864             : 
   11865             :         /* Now try a SMBtdis with the invalid vuid set to zero. */
   11866           0 :         cli_state_set_uid(cli, 0);
   11867             : 
   11868             :         /* This should succeed. */
   11869           0 :         status = cli_tdis(cli);
   11870             : 
   11871           0 :         if (NT_STATUS_IS_OK(status)) {
   11872           0 :                 d_printf("First tdis with invalid vuid should succeed.\n");
   11873             :         } else {
   11874           0 :                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
   11875           0 :                 correct = false;
   11876           0 :                 cli->smb1.tcon = tcon_copy;
   11877           0 :                 goto out;
   11878             :         }
   11879             : 
   11880           0 :         cli->smb1.tcon = tcon_copy;
   11881           0 :         cli_state_set_uid(cli, old_vuid);
   11882           0 :         cli_state_set_tid(cli, old_cnum);
   11883             : 
   11884             :         /* This should fail. */
   11885           0 :         status = cli_tdis(cli);
   11886           0 :         if (NT_STATUS_IS_OK(status)) {
   11887           0 :                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
   11888           0 :                 correct = false;
   11889           0 :                 goto out;
   11890             :         } else {
   11891             :                 /* Should be bad tid. */
   11892           0 :                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
   11893           0 :                                 NT_STATUS_NETWORK_NAME_DELETED)) {
   11894           0 :                         correct = false;
   11895           0 :                         goto out;
   11896             :                 }
   11897             :         }
   11898             : 
   11899           0 :         cli_rmdir(cli, "\\uid_reg_test");
   11900             : 
   11901           0 :   out:
   11902             : 
   11903           0 :         cli_shutdown(cli);
   11904           0 :         return correct;
   11905             : }
   11906             : 
   11907             : 
   11908             : static const char *illegal_chars = "*\\/?<>|\":";
   11909             : static char force_shortname_chars[] = " +,.[];=\177";
   11910             : 
   11911           0 : static NTSTATUS shortname_del_fn(struct file_info *finfo,
   11912             :                              const char *mask, void *state)
   11913             : {
   11914           0 :         struct cli_state *pcli = (struct cli_state *)state;
   11915             :         fstring fname;
   11916           0 :         NTSTATUS status = NT_STATUS_OK;
   11917             : 
   11918           0 :         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
   11919             : 
   11920           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
   11921           0 :                 return NT_STATUS_OK;
   11922             : 
   11923           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
   11924           0 :                 status = cli_rmdir(pcli, fname);
   11925           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11926           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
   11927             :                 }
   11928             :         } else {
   11929           0 :                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11930           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11931           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
   11932             :                 }
   11933             :         }
   11934           0 :         return status;
   11935             : }
   11936             : 
   11937             : struct sn_state {
   11938             :         int matched;
   11939             :         int i;
   11940             :         bool val;
   11941             : };
   11942             : 
   11943           0 : static NTSTATUS shortname_list_fn(struct file_info *finfo,
   11944             :                               const char *name, void *state)
   11945             : {
   11946           0 :         struct sn_state *s = (struct sn_state  *)state;
   11947           0 :         int i = s->i;
   11948             : 
   11949             : #if 0
   11950             :         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
   11951             :                 i, finfo->name, finfo->short_name);
   11952             : #endif
   11953             : 
   11954           0 :         if (strchr(force_shortname_chars, i)) {
   11955           0 :                 if (!finfo->short_name) {
   11956             :                         /* Shortname not created when it should be. */
   11957           0 :                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
   11958             :                                 __location__, finfo->name, i);
   11959           0 :                         s->val = true;
   11960             :                 }
   11961           0 :         } else if (finfo->short_name){
   11962             :                 /* Shortname created when it should not be. */
   11963           0 :                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
   11964             :                         __location__, finfo->short_name, finfo->name);
   11965           0 :                 s->val = true;
   11966             :         }
   11967           0 :         s->matched += 1;
   11968           0 :         return NT_STATUS_OK;
   11969             : }
   11970             : 
   11971           0 : static bool run_shortname_test(int dummy)
   11972             : {
   11973             :         static struct cli_state *cli;
   11974           0 :         bool correct = True;
   11975             :         int i;
   11976             :         struct sn_state s;
   11977             :         char fname[40];
   11978             :         NTSTATUS status;
   11979             : 
   11980           0 :         printf("starting shortname test\n");
   11981             : 
   11982           0 :         if (!torture_open_connection(&cli, 0)) {
   11983           0 :                 return False;
   11984             :         }
   11985             : 
   11986           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11987             : 
   11988           0 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   11989           0 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   11990           0 :         cli_rmdir(cli, "\\shortname");
   11991             : 
   11992           0 :         status = cli_mkdir(cli, "\\shortname");
   11993           0 :         if (!NT_STATUS_IS_OK(status)) {
   11994           0 :                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
   11995             :                         __location__, nt_errstr(status));
   11996           0 :                 correct = false;
   11997           0 :                 goto out;
   11998             :         }
   11999             : 
   12000           0 :         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
   12001           0 :                 correct = false;
   12002           0 :                 goto out;
   12003             :         }
   12004           0 :         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
   12005           0 :                 correct = false;
   12006           0 :                 goto out;
   12007             :         }
   12008             : 
   12009           0 :         s.val = false;
   12010             : 
   12011           0 :         for (i = 32; i < 128; i++) {
   12012           0 :                 uint16_t fnum = (uint16_t)-1;
   12013             : 
   12014           0 :                 s.i = i;
   12015             : 
   12016           0 :                 if (strchr(illegal_chars, i)) {
   12017           0 :                         continue;
   12018             :                 }
   12019           0 :                 fname[15] = i;
   12020             : 
   12021           0 :                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
   12022             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
   12023             :                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
   12024           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12025           0 :                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
   12026             :                                 __location__, fname, nt_errstr(status));
   12027           0 :                         correct = false;
   12028           0 :                         goto out;
   12029             :                 }
   12030           0 :                 cli_close(cli, fnum);
   12031             : 
   12032           0 :                 s.matched = 0;
   12033           0 :                 status = cli_list(cli, "\\shortname\\test*.*", 0,
   12034             :                                   shortname_list_fn, &s);
   12035           0 :                 if (s.matched != 1) {
   12036           0 :                         d_printf("(%s) failed to list %s: %s\n",
   12037             :                                 __location__, fname, nt_errstr(status));
   12038           0 :                         correct = false;
   12039           0 :                         goto out;
   12040             :                 }
   12041             : 
   12042           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12043           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12044           0 :                         d_printf("(%s) failed to delete %s: %s\n",
   12045             :                                 __location__, fname, nt_errstr(status));
   12046           0 :                         correct = false;
   12047           0 :                         goto out;
   12048             :                 }
   12049             : 
   12050           0 :                 if (s.val) {
   12051           0 :                         correct = false;
   12052           0 :                         goto out;
   12053             :                 }
   12054             :         }
   12055             : 
   12056           0 :   out:
   12057             : 
   12058           0 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12059           0 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12060           0 :         cli_rmdir(cli, "\\shortname");
   12061           0 :         torture_close_connection(cli);
   12062           0 :         return correct;
   12063             : }
   12064             : 
   12065             : TLDAPRC callback_code;
   12066             : 
   12067           0 : static void pagedsearch_cb(struct tevent_req *req)
   12068             : {
   12069             :         TLDAPRC rc;
   12070             :         struct tldap_message *msg;
   12071             :         char *dn;
   12072             : 
   12073           0 :         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
   12074           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12075           0 :                 d_printf("tldap_search_paged_recv failed: %s\n",
   12076             :                          tldap_rc2string(rc));
   12077           0 :                 callback_code = rc;
   12078           0 :                 return;
   12079             :         }
   12080           0 :         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
   12081           0 :                 TALLOC_FREE(msg);
   12082           0 :                 return;
   12083             :         }
   12084           0 :         if (!tldap_entry_dn(msg, &dn)) {
   12085           0 :                 d_printf("tldap_entry_dn failed\n");
   12086           0 :                 return;
   12087             :         }
   12088           0 :         d_printf("%s\n", dn);
   12089           0 :         TALLOC_FREE(msg);
   12090             : }
   12091             : 
   12092             : enum tldap_extended_val {
   12093             :         EXTENDED_ZERO = 0,
   12094             :         EXTENDED_ONE = 1,
   12095             :         EXTENDED_NONE = 2,
   12096             : };
   12097             : 
   12098             : /*
   12099             :  * Construct an extended dn control with either no value, 0 or 1
   12100             :  *
   12101             :  * No value and 0 are equivalent (non-hyphenated GUID)
   12102             :  * 1 has the hyphenated GUID
   12103             :  */
   12104             : static struct tldap_control *
   12105           0 : tldap_build_extended_control(enum tldap_extended_val val)
   12106             : {
   12107             :         struct tldap_control empty_control;
   12108             :         struct asn1_data *data;
   12109             : 
   12110           0 :         ZERO_STRUCT(empty_control);
   12111             : 
   12112           0 :         if (val != EXTENDED_NONE) {
   12113           0 :                 data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
   12114             : 
   12115           0 :                 if (!data) {
   12116           0 :                         return NULL;
   12117             :                 }
   12118             : 
   12119           0 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
   12120           0 :                         return NULL;
   12121             :                 }
   12122             : 
   12123           0 :                 if (!asn1_write_Integer(data, (int)val)) {
   12124           0 :                         return NULL;
   12125             :                 }
   12126             : 
   12127           0 :                 if (!asn1_pop_tag(data)) {
   12128           0 :                         return NULL;
   12129             :                 }
   12130             : 
   12131           0 :                 if (!asn1_blob(data, &empty_control.value)) {
   12132           0 :                         return NULL;
   12133             :                 }
   12134             :         }
   12135             : 
   12136           0 :         empty_control.oid = "1.2.840.113556.1.4.529";
   12137           0 :         empty_control.critical = true;
   12138             : 
   12139           0 :         return tldap_add_control(talloc_tos(), NULL, 0, &empty_control);
   12140             : 
   12141             : }
   12142             : 
   12143           0 : static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn,
   12144             :                                       enum tldap_extended_val control_val)
   12145             : {
   12146           0 :         struct tldap_control *control = tldap_build_extended_control(control_val);
   12147           0 :         char *dn = NULL;
   12148             :         struct tldap_message **msg;
   12149             :         TLDAPRC rc;
   12150             : 
   12151           0 :         rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE,
   12152             :                           "(objectClass=*)", NULL, 0, 0,
   12153             :                           control, 1, NULL,
   12154             :                           0, 0, 0, 0, talloc_tos(), &msg);
   12155           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12156           0 :                 d_printf("tldap_search for domain DN failed: %s\n",
   12157             :                          tldap_errstr(talloc_tos(), ld, rc));
   12158           0 :                 return false;
   12159             :         }
   12160             : 
   12161           0 :         if (!tldap_entry_dn(msg[0], &dn)) {
   12162           0 :                 d_printf("tldap_search domain DN fetch failed: %s\n",
   12163             :                          tldap_errstr(talloc_tos(), ld, rc));
   12164           0 :                 return false;
   12165             :         }
   12166             : 
   12167           0 :         d_printf("%s\n", dn);
   12168             :         {
   12169             :                 uint32_t time_low;
   12170             :                 uint32_t time_mid, time_hi_and_version;
   12171             :                 uint32_t clock_seq[2];
   12172             :                 uint32_t node[6];
   12173             :                 char next;
   12174             : 
   12175           0 :                 switch (control_val) {
   12176           0 :                 case EXTENDED_NONE:
   12177             :                 case EXTENDED_ZERO:
   12178             :                         /*
   12179             :                          * When reading GUIDs with hyphens, scanf will treat
   12180             :                          * hyphen as a hex character (and counts as part of the
   12181             :                          * width). This creates leftover GUID string which we
   12182             :                          * check will for with 'next' and closing '>'.
   12183             :                          */
   12184           0 :                         if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
   12185             :                                          &time_low, &time_mid,
   12186             :                                          &time_hi_and_version, &clock_seq[0],
   12187             :                                          &clock_seq[1], &node[0], &node[1],
   12188             :                                          &node[2], &node[3], &node[4],
   12189             :                                          &node[5], &next)) {
   12190             :                                 /* This GUID is good */
   12191             :                         } else {
   12192           0 :                                 d_printf("GUID format in control (no hyphens) doesn't match output\n");
   12193           0 :                                 return false;
   12194             :                         }
   12195             : 
   12196           0 :                         break;
   12197           0 :                 case EXTENDED_ONE:
   12198           0 :                         if (12 == sscanf(dn,
   12199             :                                          "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
   12200             :                                          &time_low, &time_mid,
   12201             :                                          &time_hi_and_version, &clock_seq[0],
   12202             :                                          &clock_seq[1], &node[0], &node[1],
   12203             :                                          &node[2], &node[3], &node[4],
   12204             :                                          &node[5], &next)) {
   12205             :                                 /* This GUID is good */
   12206             :                         } else {
   12207           0 :                                 d_printf("GUID format in control (with hyphens) doesn't match output\n");
   12208           0 :                                 return false;
   12209             :                         }
   12210             : 
   12211           0 :                         break;
   12212           0 :                 default:
   12213           0 :                         return false;
   12214             :                 }
   12215             :         }
   12216             : 
   12217           0 :         return true;
   12218             : }
   12219             : 
   12220           0 : static bool run_tldap(int dummy)
   12221             : {
   12222             :         struct tldap_context *ld;
   12223             :         int fd;
   12224             :         TLDAPRC rc;
   12225             :         NTSTATUS status;
   12226             :         struct sockaddr_storage addr;
   12227             :         struct tevent_context *ev;
   12228             :         struct tevent_req *req;
   12229             :         char *basedn;
   12230             :         const char *filter;
   12231             : 
   12232           0 :         if (!resolve_name(host, &addr, 0, false)) {
   12233           0 :                 d_printf("could not find host %s\n", host);
   12234           0 :                 return false;
   12235             :         }
   12236           0 :         status = open_socket_out(&addr, 389, 9999, &fd);
   12237           0 :         if (!NT_STATUS_IS_OK(status)) {
   12238           0 :                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
   12239           0 :                 return false;
   12240             :         }
   12241             : 
   12242           0 :         ld = tldap_context_create(talloc_tos(), fd);
   12243           0 :         if (ld == NULL) {
   12244           0 :                 close(fd);
   12245           0 :                 d_printf("tldap_context_create failed\n");
   12246           0 :                 return false;
   12247             :         }
   12248             : 
   12249           0 :         rc = tldap_fetch_rootdse(ld);
   12250           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12251           0 :                 d_printf("tldap_fetch_rootdse failed: %s\n",
   12252             :                          tldap_errstr(talloc_tos(), ld, rc));
   12253           0 :                 return false;
   12254             :         }
   12255             : 
   12256           0 :         basedn = tldap_talloc_single_attribute(
   12257             :                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
   12258           0 :         if (basedn == NULL) {
   12259           0 :                 d_printf("no defaultNamingContext\n");
   12260           0 :                 return false;
   12261             :         }
   12262           0 :         d_printf("defaultNamingContext: %s\n", basedn);
   12263             : 
   12264           0 :         ev = samba_tevent_context_init(talloc_tos());
   12265           0 :         if (ev == NULL) {
   12266           0 :                 d_printf("tevent_context_init failed\n");
   12267           0 :                 return false;
   12268             :         }
   12269             : 
   12270           0 :         rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL,
   12271             :                                loadparm_init_s3(talloc_tos(),
   12272             :                                                 loadparm_s3_helpers()),
   12273             :                                GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
   12274             : 
   12275           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12276           0 :                 d_printf("tldap_gensec_bind failed\n");
   12277           0 :                 return false;
   12278             :         }
   12279             : 
   12280           0 :         callback_code = TLDAP_SUCCESS;
   12281             : 
   12282           0 :         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
   12283             :                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
   12284             :                                       NULL, 0, 0,
   12285             :                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
   12286           0 :         if (req == NULL) {
   12287           0 :                 d_printf("tldap_search_paged_send failed\n");
   12288           0 :                 return false;
   12289             :         }
   12290           0 :         tevent_req_set_callback(req, pagedsearch_cb, NULL);
   12291             : 
   12292           0 :         tevent_req_poll(req, ev);
   12293             : 
   12294           0 :         TALLOC_FREE(req);
   12295             : 
   12296           0 :         rc = callback_code;
   12297             : 
   12298           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12299           0 :                 d_printf("tldap_search with paging failed: %s\n",
   12300             :                          tldap_errstr(talloc_tos(), ld, rc));
   12301           0 :                 return false;
   12302             :         }
   12303             : 
   12304             :         /* test search filters against rootDSE */
   12305           0 :         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
   12306             :                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
   12307             : 
   12308           0 :         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
   12309             :                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
   12310             :                           talloc_tos(), NULL);
   12311           0 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12312           0 :                 d_printf("tldap_search with complex filter failed: %s\n",
   12313             :                          tldap_errstr(talloc_tos(), ld, rc));
   12314           0 :                 return false;
   12315             :         }
   12316             : 
   12317             :         /*
   12318             :          * Tests to check for regression of:
   12319             :          *
   12320             :          * https://bugzilla.samba.org/show_bug.cgi?id=14029
   12321             :          *
   12322             :          * TLDAP used here to pick apart the original string DN (with GUID)
   12323             :          */
   12324           0 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) {
   12325           0 :                 d_printf("tldap_search with extended dn (no val) failed: %s\n",
   12326             :                          tldap_errstr(talloc_tos(), ld, rc));
   12327           0 :                 return false;
   12328             :         }
   12329           0 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) {
   12330           0 :                 d_printf("tldap_search with extended dn (0) failed: %s\n",
   12331             :                          tldap_errstr(talloc_tos(), ld, rc));
   12332           0 :                 return false;
   12333             :         }
   12334           0 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) {
   12335           0 :                 d_printf("tldap_search with extended dn (1) failed: %s\n",
   12336             :                          tldap_errstr(talloc_tos(), ld, rc));
   12337           0 :                 return false;
   12338             :         }
   12339             : 
   12340           0 :         TALLOC_FREE(ld);
   12341           0 :         return true;
   12342             : }
   12343             : 
   12344             : /* Torture test to ensure no regression of :
   12345             : https://bugzilla.samba.org/show_bug.cgi?id=7084
   12346             : */
   12347             : 
   12348           0 : static bool run_dir_createtime(int dummy)
   12349             : {
   12350             :         struct cli_state *cli;
   12351           0 :         const char *dname = "\\testdir_createtime";
   12352           0 :         const char *fname = "\\testdir_createtime\\testfile";
   12353             :         NTSTATUS status;
   12354             :         struct timespec create_time;
   12355             :         struct timespec create_time1;
   12356             :         uint16_t fnum;
   12357           0 :         bool ret = false;
   12358             :         uint64_t ino;
   12359             : 
   12360           0 :         if (!torture_open_connection(&cli, 0)) {
   12361           0 :                 return false;
   12362             :         }
   12363             : 
   12364           0 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12365             :                 /* Ensure ino is zero, SMB2 gets a real one. */
   12366           0 :                 ino = 0;
   12367             :         } else {
   12368             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
   12369           0 :                 ino = (uint64_t)-1;
   12370             :         }
   12371             : 
   12372           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12373           0 :         cli_rmdir(cli, dname);
   12374             : 
   12375           0 :         status = cli_mkdir(cli, dname);
   12376           0 :         if (!NT_STATUS_IS_OK(status)) {
   12377           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12378           0 :                 goto out;
   12379             :         }
   12380             : 
   12381           0 :         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
   12382             :                                 NULL, NULL, &ino);
   12383           0 :         if (!NT_STATUS_IS_OK(status)) {
   12384           0 :                 printf("cli_qpathinfo2 returned %s\n",
   12385             :                        nt_errstr(status));
   12386           0 :                 goto out;
   12387             :         }
   12388             : 
   12389           0 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12390             :                 /* SMB2 should always return an inode. */
   12391           0 :                 if (ino == 0) {
   12392           0 :                         printf("SMB2 bad inode (0)\n");
   12393           0 :                         goto out;
   12394             :                 }
   12395             :         } else {
   12396             :                 /* SMB1 must always return zero here. */
   12397           0 :                 if (ino != 0) {
   12398           0 :                         printf("SMB1 bad inode (!0)\n");
   12399           0 :                         goto out;
   12400             :                 }
   12401             :         }
   12402             : 
   12403             :         /* Sleep 3 seconds, then create a file. */
   12404           0 :         sleep(3);
   12405             : 
   12406           0 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
   12407             :                          DENY_NONE, &fnum);
   12408           0 :         if (!NT_STATUS_IS_OK(status)) {
   12409           0 :                 printf("cli_openx failed: %s\n", nt_errstr(status));
   12410           0 :                 goto out;
   12411             :         }
   12412             : 
   12413           0 :         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
   12414             :                                 NULL, NULL, NULL);
   12415           0 :         if (!NT_STATUS_IS_OK(status)) {
   12416           0 :                 printf("cli_qpathinfo2 (2) returned %s\n",
   12417             :                        nt_errstr(status));
   12418           0 :                 goto out;
   12419             :         }
   12420             : 
   12421           0 :         if (timespec_compare(&create_time1, &create_time)) {
   12422           0 :                 printf("run_dir_createtime: create time was updated (error)\n");
   12423             :         } else {
   12424           0 :                 printf("run_dir_createtime: create time was not updated (correct)\n");
   12425           0 :                 ret = true;
   12426             :         }
   12427             : 
   12428           0 :   out:
   12429             : 
   12430           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12431           0 :         cli_rmdir(cli, dname);
   12432           0 :         if (!torture_close_connection(cli)) {
   12433           0 :                 ret = false;
   12434             :         }
   12435           0 :         return ret;
   12436             : }
   12437             : 
   12438             : 
   12439           0 : static bool run_streamerror(int dummy)
   12440             : {
   12441             :         struct cli_state *cli;
   12442           0 :         const char *dname = "\\testdir_streamerror";
   12443           0 :         const char *streamname =
   12444             :                 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
   12445             :         NTSTATUS status;
   12446             :         time_t change_time, access_time, write_time;
   12447             :         off_t size;
   12448             :         uint16_t fnum;
   12449             :         uint32_t attr;
   12450           0 :         bool ret = true;
   12451             : 
   12452           0 :         if (!torture_open_connection(&cli, 0)) {
   12453           0 :                 return false;
   12454             :         }
   12455             : 
   12456           0 :         torture_deltree(cli, dname);
   12457             : 
   12458           0 :         status = cli_mkdir(cli, dname);
   12459           0 :         if (!NT_STATUS_IS_OK(status)) {
   12460           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12461           0 :                 return false;
   12462             :         }
   12463             : 
   12464           0 :         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
   12465             :                                 &write_time, &size, &attr);
   12466           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12467           0 :                 printf("pathinfo returned %s, expected "
   12468             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12469             :                        nt_errstr(status));
   12470           0 :                 ret = false;
   12471             :         }
   12472             : 
   12473           0 :         status = cli_ntcreate(cli, streamname, 0x16,
   12474             :                               FILE_READ_DATA|FILE_READ_EA|
   12475             :                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
   12476             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
   12477             :                               FILE_OPEN, 0, 0, &fnum, NULL);
   12478             : 
   12479           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12480           0 :                 printf("ntcreate returned %s, expected "
   12481             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12482             :                        nt_errstr(status));
   12483           0 :                 ret = false;
   12484             :         }
   12485             : 
   12486             : 
   12487           0 :         cli_rmdir(cli, dname);
   12488           0 :         return ret;
   12489             : }
   12490             : 
   12491             : struct pidtest_state {
   12492             :         bool success;
   12493             :         uint16_t vwv[1];
   12494             :         DATA_BLOB data;
   12495             : };
   12496             : 
   12497             : static void pid_echo_done(struct tevent_req *subreq);
   12498             : 
   12499           0 : static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
   12500             :                         struct tevent_context *ev,
   12501             :                         struct cli_state *cli)
   12502             : {
   12503             :         struct tevent_req *req, *subreq;
   12504             :         struct pidtest_state *state;
   12505             : 
   12506           0 :         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
   12507           0 :         if (req == NULL) {
   12508           0 :                 return NULL;
   12509             :         }
   12510             : 
   12511           0 :         SSVAL(state->vwv, 0, 1);
   12512           0 :         state->data = data_blob_const("hello", 5);
   12513             : 
   12514           0 :         subreq = smb1cli_req_send(state,
   12515             :                                 ev,
   12516             :                                 cli->conn,
   12517             :                                 SMBecho,
   12518             :                                 0, 0, /* *_flags */
   12519             :                                 0, 0, /* *_flags2 */
   12520           0 :                                 cli->timeout,
   12521             :                                 0xDEADBEEF, /* pid */
   12522             :                                 NULL, /* tcon */
   12523             :                                 NULL, /* session */
   12524           0 :                                 ARRAY_SIZE(state->vwv), state->vwv,
   12525           0 :                                 state->data.length, state->data.data);
   12526             : 
   12527           0 :         if (tevent_req_nomem(subreq, req)) {
   12528           0 :                 return tevent_req_post(req, ev);
   12529             :         }
   12530           0 :         tevent_req_set_callback(subreq, pid_echo_done, req);
   12531           0 :         return req;
   12532             : }
   12533             : 
   12534           0 : static void pid_echo_done(struct tevent_req *subreq)
   12535             : {
   12536           0 :         struct tevent_req *req = tevent_req_callback_data(
   12537             :                 subreq, struct tevent_req);
   12538           0 :         struct pidtest_state *state = tevent_req_data(
   12539             :                 req, struct pidtest_state);
   12540             :         NTSTATUS status;
   12541             :         uint32_t num_bytes;
   12542           0 :         uint8_t *bytes = NULL;
   12543           0 :         struct iovec *recv_iov = NULL;
   12544           0 :         uint8_t *phdr = NULL;
   12545           0 :         uint16_t pidlow = 0;
   12546           0 :         uint16_t pidhigh = 0;
   12547           0 :         struct smb1cli_req_expected_response expected[] = {
   12548             :         {
   12549             :                 .status = NT_STATUS_OK,
   12550             :                 .wct    = 1,
   12551             :         },
   12552             :         };
   12553             : 
   12554           0 :         status = smb1cli_req_recv(subreq, state,
   12555             :                                 &recv_iov,
   12556             :                                 &phdr,
   12557             :                                 NULL, /* pwct */
   12558             :                                 NULL, /* pvwv */
   12559             :                                 NULL, /* pvwv_offset */
   12560             :                                 &num_bytes,
   12561             :                                 &bytes,
   12562             :                                 NULL, /* pbytes_offset */
   12563             :                                 NULL, /* pinbuf */
   12564             :                                 expected, ARRAY_SIZE(expected));
   12565             : 
   12566           0 :         TALLOC_FREE(subreq);
   12567             : 
   12568           0 :         if (!NT_STATUS_IS_OK(status)) {
   12569           0 :                 tevent_req_nterror(req, status);
   12570           0 :                 return;
   12571             :         }
   12572             : 
   12573           0 :         if (num_bytes != state->data.length) {
   12574           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12575           0 :                 return;
   12576             :         }
   12577             : 
   12578           0 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
   12579           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12580           0 :                 return;
   12581             :         }
   12582             : 
   12583             :         /* Check pid low/high == DEADBEEF */
   12584           0 :         pidlow = SVAL(phdr, HDR_PID);
   12585           0 :         if (pidlow != 0xBEEF){
   12586           0 :                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
   12587             :                         (unsigned int)pidlow);
   12588           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12589           0 :                 return;
   12590             :         }
   12591           0 :         pidhigh = SVAL(phdr, HDR_PIDHIGH);
   12592           0 :         if (pidhigh != 0xDEAD){
   12593           0 :                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
   12594             :                         (unsigned int)pidhigh);
   12595           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12596           0 :                 return;
   12597             :         }
   12598             : 
   12599           0 :         tevent_req_done(req);
   12600             : }
   12601             : 
   12602           0 : static NTSTATUS pid_echo_recv(struct tevent_req *req)
   12603             : {
   12604           0 :         return tevent_req_simple_recv_ntstatus(req);
   12605             : }
   12606             : 
   12607           0 : static bool run_pidhigh(int dummy)
   12608             : {
   12609           0 :         bool success = false;
   12610           0 :         struct cli_state *cli = NULL;
   12611             :         NTSTATUS status;
   12612           0 :         struct tevent_context *ev = NULL;
   12613           0 :         struct tevent_req *req = NULL;
   12614           0 :         TALLOC_CTX *frame = talloc_stackframe();
   12615             : 
   12616           0 :         printf("starting pid high test\n");
   12617           0 :         if (!torture_open_connection(&cli, 0)) {
   12618           0 :                 return false;
   12619             :         }
   12620           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12621             : 
   12622           0 :         ev = samba_tevent_context_init(frame);
   12623           0 :         if (ev == NULL) {
   12624           0 :                 goto fail;
   12625             :         }
   12626             : 
   12627           0 :         req = pid_echo_send(frame, ev, cli);
   12628           0 :         if (req == NULL) {
   12629           0 :                 goto fail;
   12630             :         }
   12631             : 
   12632           0 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
   12633           0 :                 goto fail;
   12634             :         }
   12635             : 
   12636           0 :         status = pid_echo_recv(req);
   12637           0 :         if (NT_STATUS_IS_OK(status)) {
   12638           0 :                 printf("pid high test ok\n");
   12639           0 :                 success = true;
   12640             :         }
   12641             : 
   12642           0 :  fail:
   12643             : 
   12644           0 :         TALLOC_FREE(frame);
   12645           0 :         torture_close_connection(cli);
   12646           0 :         return success;
   12647             : }
   12648             : 
   12649             : /*
   12650             :   Test Windows open on a bad POSIX symlink.
   12651             :  */
   12652           0 : static bool run_symlink_open_test(int dummy)
   12653             : {
   12654             :         static struct cli_state *cli;
   12655           0 :         const char *fname = "non_existant_file";
   12656           0 :         const char *sname = "dangling_symlink";
   12657           0 :         uint16_t fnum = (uint16_t)-1;
   12658           0 :         bool correct = false;
   12659             :         NTSTATUS status;
   12660           0 :         TALLOC_CTX *frame = NULL;
   12661             : 
   12662           0 :         frame = talloc_stackframe();
   12663             : 
   12664           0 :         printf("Starting Windows bad symlink open test\n");
   12665             : 
   12666           0 :         if (!torture_open_connection(&cli, 0)) {
   12667           0 :                 TALLOC_FREE(frame);
   12668           0 :                 return false;
   12669             :         }
   12670             : 
   12671           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12672             : 
   12673           0 :         status = torture_setup_unix_extensions(cli);
   12674           0 :         if (!NT_STATUS_IS_OK(status)) {
   12675           0 :                 TALLOC_FREE(frame);
   12676           0 :                 return false;
   12677             :         }
   12678             : 
   12679             :         /* Ensure nothing exists. */
   12680           0 :         cli_setatr(cli, fname, 0, 0);
   12681           0 :         cli_posix_unlink(cli, fname);
   12682           0 :         cli_setatr(cli, sname, 0, 0);
   12683           0 :         cli_posix_unlink(cli, sname);
   12684             : 
   12685             :         /* Create a symlink pointing nowhere. */
   12686           0 :         status = cli_posix_symlink(cli, fname, sname);
   12687           0 :         if (!NT_STATUS_IS_OK(status)) {
   12688           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
   12689             :                         sname,
   12690             :                         fname,
   12691             :                         nt_errstr(status));
   12692           0 :                 goto out;
   12693             :         }
   12694             : 
   12695             :         /* Now ensure that a Windows open doesn't hang. */
   12696           0 :         status = cli_ntcreate(cli,
   12697             :                         sname,
   12698             :                         0,
   12699             :                         FILE_READ_DATA|FILE_WRITE_DATA,
   12700             :                         0,
   12701             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   12702             :                         FILE_OPEN_IF,
   12703             :                         0x0,
   12704             :                         0x0,
   12705             :                         &fnum,
   12706             :                         NULL);
   12707             : 
   12708             :         /*
   12709             :          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
   12710             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
   12711             :          * we use O_NOFOLLOW on the server or not.
   12712             :          */
   12713           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
   12714           0 :             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
   12715             :         {
   12716           0 :                 correct = true;
   12717             :         } else {
   12718           0 :                 printf("cli_ntcreate of %s returned %s - should return"
   12719             :                                 " either (%s) or (%s)\n",
   12720             :                         sname,
   12721             :                         nt_errstr(status),
   12722           0 :                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
   12723           0 :                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
   12724           0 :                 goto out;
   12725             :         }
   12726             : 
   12727           0 :         correct = true;
   12728             : 
   12729           0 :   out:
   12730             : 
   12731           0 :         if (fnum != (uint16_t)-1) {
   12732           0 :                 cli_close(cli, fnum);
   12733           0 :                 fnum = (uint16_t)-1;
   12734             :         }
   12735             : 
   12736           0 :         cli_setatr(cli, sname, 0, 0);
   12737           0 :         cli_posix_unlink(cli, sname);
   12738           0 :         cli_setatr(cli, fname, 0, 0);
   12739           0 :         cli_posix_unlink(cli, fname);
   12740             : 
   12741           0 :         if (!torture_close_connection(cli)) {
   12742           0 :                 correct = false;
   12743             :         }
   12744             : 
   12745           0 :         TALLOC_FREE(frame);
   12746           0 :         return correct;
   12747             : }
   12748             : 
   12749           0 : static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
   12750             :                                         const char *name,
   12751             :                                         void *state)
   12752             : {
   12753           0 :         char **mangled_name_return = (char **)state;
   12754           0 :         bool is_mangled = strchr(finfo->name, '~');
   12755             : 
   12756           0 :         if (is_mangled) {
   12757           0 :                 *mangled_name_return = talloc_strdup(NULL, finfo->name);
   12758           0 :                 if (*mangled_name_return == NULL) {
   12759           0 :                         return NT_STATUS_NO_MEMORY;
   12760             :                 }
   12761             :         }
   12762           0 :         return NT_STATUS_OK;
   12763             : }
   12764             : 
   12765           0 : static bool run_smb1_wild_mangle_unlink_test(int dummy)
   12766             : {
   12767             :         static struct cli_state *cli_posix = NULL;
   12768             :         static struct cli_state *cli = NULL;
   12769           0 :         uint16_t fnum = (uint16_t)-1;
   12770           0 :         bool correct = false;
   12771           0 :         const char *dname = "smb1_wild_mangle_unlink";
   12772           0 :         const char *aname = "smb1_wild_mangle_unlink/a";
   12773           0 :         const char *star_name = "smb1_wild_mangle_unlink/*";
   12774           0 :         char *windows_unlink_name = NULL;
   12775           0 :         char *mangled_name = NULL;
   12776             :         NTSTATUS status;
   12777             : 
   12778           0 :         printf("Starting SMB1 wild mangle unlink test\n");
   12779             : 
   12780             :         /* Open a Windows connection. */
   12781           0 :         if (!torture_open_connection(&cli, 0)) {
   12782           0 :                 return false;
   12783             :         }
   12784             : 
   12785           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12786             : 
   12787             :         /* Open a POSIX connection. */
   12788           0 :         if (!torture_open_connection(&cli_posix, 0)) {
   12789           0 :                 goto out;
   12790             :         }
   12791             : 
   12792           0 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12793             : 
   12794           0 :         status = torture_setup_unix_extensions(cli_posix);
   12795           0 :         if (!NT_STATUS_IS_OK(status)) {
   12796           0 :                 printf("server doesn't support POSIX\n");
   12797           0 :                 goto out;
   12798             :         }
   12799             : 
   12800             :         /* Start fresh. */
   12801           0 :         torture_deltree(cli, dname);
   12802             : 
   12803             :         /*
   12804             :          * Create two files - 'a' and '*'.
   12805             :          * We need POSIX extensions for this as '*'
   12806             :          * is not a valid Windows name.
   12807             :          */
   12808             : 
   12809           0 :         status = cli_mkdir(cli, dname);
   12810           0 :         if (!NT_STATUS_IS_OK(status)) {
   12811           0 :                 printf("cli_mkdir of %s returned %s\n",
   12812             :                         dname,
   12813             :                         nt_errstr(status));
   12814           0 :                 goto out;
   12815             :         }
   12816             : 
   12817           0 :         status = cli_posix_open(cli_posix,
   12818             :                                 aname,
   12819             :                                 O_RDWR|O_CREAT|O_EXCL,
   12820             :                                 0660,
   12821             :                                 &fnum);
   12822           0 :         if (!NT_STATUS_IS_OK(status)) {
   12823           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12824             :                         aname,
   12825             :                         nt_errstr(status));
   12826           0 :                 goto out;
   12827             :         }
   12828           0 :         status = cli_close(cli_posix, fnum);
   12829           0 :         if (!NT_STATUS_IS_OK(status)) {
   12830           0 :                 goto out;
   12831             :         }
   12832           0 :         status = cli_posix_open(cli_posix,
   12833             :                                 star_name,
   12834             :                                 O_RDWR|O_CREAT|O_EXCL,
   12835             :                                 0660,
   12836             :                                 &fnum);
   12837           0 :         if (!NT_STATUS_IS_OK(status)) {
   12838           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12839             :                         star_name,
   12840             :                         nt_errstr(status));
   12841           0 :                 goto out;
   12842             :         }
   12843           0 :         status = cli_close(cli_posix, fnum);
   12844           0 :         if (!NT_STATUS_IS_OK(status)) {
   12845           0 :                 goto out;
   12846             :         }
   12847             : 
   12848           0 :         status = cli_list(cli,
   12849             :                         star_name,
   12850             :                         0,
   12851             :                         smb1_wild_mangle_list_fn,
   12852             :                         &mangled_name);
   12853           0 :         if (!NT_STATUS_IS_OK(status)) {
   12854           0 :                 printf("cli_list of %s returned %s\n",
   12855             :                         star_name,
   12856             :                         nt_errstr(status));
   12857           0 :                 goto out;
   12858             :         }
   12859             : 
   12860           0 :         if (mangled_name == NULL) {
   12861           0 :                 goto out;
   12862             :         }
   12863             : 
   12864           0 :         printf("mangled_name = %s\n",
   12865             :                 mangled_name);
   12866             : 
   12867             :         /*
   12868             :          * Try a Windows unlink with the mangled name.
   12869             :          * This should *NOT* unlink the 'a' name.
   12870             :          */
   12871             : 
   12872           0 :         windows_unlink_name = talloc_asprintf(cli_posix,
   12873             :                                         "%s\\%s",
   12874             :                                         dname,
   12875             :                                         mangled_name);
   12876             : 
   12877           0 :         status = cli_unlink(cli, windows_unlink_name, 0);
   12878           0 :         if (!NT_STATUS_IS_OK(status)) {
   12879           0 :                 printf("cli_unlink of %s returned %s\n",
   12880             :                         windows_unlink_name,
   12881             :                         nt_errstr(status));
   12882           0 :                 goto out;
   12883             :         }
   12884             : 
   12885             :         /* Does 'a' still exist ? */
   12886           0 :         status = cli_posix_open(cli_posix,
   12887             :                                 aname,
   12888             :                                 O_RDONLY,
   12889             :                                 0,
   12890             :                                 &fnum);
   12891           0 :         if (!NT_STATUS_IS_OK(status)) {
   12892           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   12893             :                         aname,
   12894             :                         nt_errstr(status));
   12895           0 :                 goto out;
   12896             :         }
   12897             : 
   12898           0 :         status = cli_close(cli_posix, fnum);
   12899           0 :         if (!NT_STATUS_IS_OK(status)) {
   12900           0 :                 goto out;
   12901             :         }
   12902             : 
   12903           0 :         correct = true;
   12904             : 
   12905           0 :   out:
   12906             : 
   12907           0 :         TALLOC_FREE(windows_unlink_name);
   12908           0 :         TALLOC_FREE(mangled_name);
   12909             : 
   12910           0 :         if (cli != NULL) {
   12911           0 :                 torture_deltree(cli, dname);
   12912           0 :                 torture_close_connection(cli);
   12913             :         }
   12914             : 
   12915           0 :         if (cli_posix != NULL) {
   12916           0 :                 torture_close_connection(cli_posix);
   12917             :         }
   12918             : 
   12919           0 :         return correct;
   12920             : }
   12921             : 
   12922           0 : static bool run_smb1_wild_mangle_rename_test(int dummy)
   12923             : {
   12924             :         static struct cli_state *cli_posix = NULL;
   12925             :         static struct cli_state *cli = NULL;
   12926           0 :         uint16_t fnum = (uint16_t)-1;
   12927           0 :         bool correct = false;
   12928           0 :         const char *dname = "smb1_wild_mangle_rename";
   12929           0 :         const char *fooname = "smb1_wild_mangle_rename/foo";
   12930           0 :         const char *foostar_name = "smb1_wild_mangle_rename/fo*";
   12931           0 :         const char *wild_name = "smb1_wild_mangle_rename/*";
   12932           0 :         char *windows_rename_src = NULL;
   12933           0 :         const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
   12934           0 :         char *mangled_name = NULL;
   12935             :         NTSTATUS status;
   12936             : 
   12937           0 :         printf("Starting SMB1 wild mangle rename test\n");
   12938             : 
   12939           0 :         if (!torture_open_connection(&cli_posix, 0)) {
   12940           0 :                 return false;
   12941             :         }
   12942             : 
   12943           0 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12944             : 
   12945           0 :         status = torture_setup_unix_extensions(cli_posix);
   12946           0 :         if (!NT_STATUS_IS_OK(status)) {
   12947           0 :                 printf("server doesn't support POSIX\n");
   12948           0 :                 return false;
   12949             :         }
   12950             : 
   12951             :         /* Open a Windows connection. */
   12952           0 :         if (!torture_open_connection(&cli, 0)) {
   12953           0 :                 goto out;
   12954             :         }
   12955             : 
   12956           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12957             : 
   12958             :         /* Ensure we start from fresh. */
   12959           0 :         torture_deltree(cli, dname);
   12960             : 
   12961             :         /*
   12962             :          * Create two files - 'foo' and 'fo*'.
   12963             :          * We need POSIX extensions for this as 'fo*'
   12964             :          * is not a valid Windows name.
   12965             :          */
   12966             : 
   12967           0 :         status = cli_posix_mkdir(cli_posix, dname, 0770);
   12968           0 :         if (!NT_STATUS_IS_OK(status)) {
   12969           0 :                 printf("cli_posix_mkdir of %s returned %s\n",
   12970             :                         dname,
   12971             :                         nt_errstr(status));
   12972           0 :                 goto out;
   12973             :         }
   12974             : 
   12975           0 :         status = cli_posix_open(cli_posix,
   12976             :                                 fooname,
   12977             :                                 O_RDWR|O_CREAT|O_EXCL,
   12978             :                                 0660,
   12979             :                                 &fnum);
   12980           0 :         if (!NT_STATUS_IS_OK(status)) {
   12981           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12982             :                         fooname,
   12983             :                         nt_errstr(status));
   12984           0 :                 goto out;
   12985             :         }
   12986           0 :         status = cli_close(cli_posix, fnum);
   12987           0 :         if (!NT_STATUS_IS_OK(status)) {
   12988           0 :                 goto out;
   12989             :         }
   12990           0 :         status = cli_posix_open(cli_posix,
   12991             :                                 foostar_name,
   12992             :                                 O_RDWR|O_CREAT|O_EXCL,
   12993             :                                 0660,
   12994             :                                 &fnum);
   12995           0 :         if (!NT_STATUS_IS_OK(status)) {
   12996           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12997             :                         foostar_name,
   12998             :                         nt_errstr(status));
   12999           0 :                 goto out;
   13000             :         }
   13001           0 :         status = cli_close(cli_posix, fnum);
   13002           0 :         if (!NT_STATUS_IS_OK(status)) {
   13003           0 :                 goto out;
   13004             :         }
   13005             : 
   13006             :         /*
   13007             :          * Get the mangled name. We can re-use the
   13008             :          * previous smb1_wild_mangle_list_fn for this.
   13009             :          */
   13010             : 
   13011           0 :         status = cli_list(cli,
   13012             :                         wild_name,
   13013             :                         0,
   13014             :                         smb1_wild_mangle_list_fn,
   13015             :                         &mangled_name);
   13016           0 :         if (!NT_STATUS_IS_OK(status)) {
   13017           0 :                 printf("cli_list of %s returned %s\n",
   13018             :                         wild_name,
   13019             :                         nt_errstr(status));
   13020           0 :                 goto out;
   13021             :         }
   13022             : 
   13023           0 :         if (mangled_name == NULL) {
   13024           0 :                 goto out;
   13025             :         }
   13026             : 
   13027           0 :         printf("mangled_name = %s\n",
   13028             :                 mangled_name);
   13029             : 
   13030             :         /*
   13031             :          * Try a Windows rename with the mangled name.
   13032             :          * This should *NOT* rename the 'foo' name.
   13033             :          */
   13034             : 
   13035           0 :         windows_rename_src = talloc_asprintf(cli_posix,
   13036             :                                         "%s\\%s",
   13037             :                                         dname,
   13038             :                                         mangled_name);
   13039             : 
   13040           0 :         status = cli_rename(cli,
   13041             :                         windows_rename_src,
   13042             :                         windows_rename_dst,
   13043             :                         false);
   13044           0 :         if (!NT_STATUS_IS_OK(status)) {
   13045           0 :                 printf("cli_rename of %s -> %s returned %s\n",
   13046             :                         windows_rename_src,
   13047             :                         windows_rename_dst,
   13048             :                         nt_errstr(status));
   13049           0 :                 goto out;
   13050             :         }
   13051             : 
   13052             :         /* Does 'foo' still exist ? */
   13053           0 :         status = cli_posix_open(cli_posix,
   13054             :                                 fooname,
   13055             :                                 O_RDONLY,
   13056             :                                 0,
   13057             :                                 &fnum);
   13058           0 :         if (!NT_STATUS_IS_OK(status)) {
   13059           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13060             :                         fooname,
   13061             :                         nt_errstr(status));
   13062           0 :                 goto out;
   13063             :         }
   13064             : 
   13065           0 :         status = cli_close(cli_posix, fnum);
   13066           0 :         if (!NT_STATUS_IS_OK(status)) {
   13067           0 :                 goto out;
   13068             :         }
   13069             : 
   13070           0 :         correct = true;
   13071             : 
   13072           0 :   out:
   13073             : 
   13074           0 :         TALLOC_FREE(mangled_name);
   13075           0 :         TALLOC_FREE(windows_rename_src);
   13076             : 
   13077           0 :         if (cli != NULL) {
   13078           0 :                 torture_deltree(cli, dname);
   13079           0 :                 torture_close_connection(cli);
   13080             :         }
   13081             : 
   13082           0 :         torture_close_connection(cli_posix);
   13083             : 
   13084           0 :         return correct;
   13085             : }
   13086             : 
   13087             : /*
   13088             :  * Only testing minimal time strings, as the others
   13089             :  * need (locale-dependent) guessing at what strftime does and
   13090             :  * even may differ in builds.
   13091             :  */
   13092           0 : static bool timesubst_test(void)
   13093             : {
   13094           0 :         TALLOC_CTX *ctx = NULL;
   13095             :         /* Sa 23. Dez 04:33:20 CET 2017 */
   13096           0 :         const struct timeval tv = { 1514000000, 123 };
   13097           0 :         const char* expect_minimal = "20171223_033320";
   13098           0 :         const char* expect_minus   = "20171223_033320_000123";
   13099             :         char *s;
   13100           0 :         char *env_tz, *orig_tz = NULL;
   13101           0 :         bool result = true;
   13102             : 
   13103           0 :         ctx = talloc_new(NULL);
   13104             : 
   13105           0 :         env_tz = getenv("TZ");
   13106           0 :         if(env_tz) {
   13107           0 :                 orig_tz = talloc_strdup(ctx, env_tz);
   13108             :         }
   13109           0 :         setenv("TZ", "UTC", 1);
   13110             : 
   13111           0 :         s = minimal_timeval_string(ctx, &tv, false);
   13112             : 
   13113           0 :         if(!s || strcmp(s, expect_minimal)) {
   13114           0 :                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
   13115             :                        "[%s]\n", s ? s : "<nil>", expect_minimal);
   13116           0 :                 result = false;
   13117             :         }
   13118           0 :         TALLOC_FREE(s);
   13119           0 :         s = minimal_timeval_string(ctx, &tv, true);
   13120           0 :         if(!s || strcmp(s, expect_minus)) {
   13121           0 :                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
   13122             :                        "[%s]\n", s ? s : "<nil>", expect_minus);
   13123           0 :                 result = false;
   13124             :         }
   13125           0 :         TALLOC_FREE(s);
   13126             : 
   13127           0 :         if(orig_tz) {
   13128           0 :                 setenv("TZ", orig_tz, 1);
   13129             :         }
   13130             : 
   13131           0 :         TALLOC_FREE(ctx);
   13132           0 :         return result;
   13133             : }
   13134             : 
   13135           0 : static bool run_local_substitute(int dummy)
   13136             : {
   13137           0 :         bool ok = true;
   13138             : 
   13139           0 :         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
   13140           0 :         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
   13141           0 :         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
   13142           0 :         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
   13143           0 :         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
   13144           0 :         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
   13145           0 :         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
   13146           0 :         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
   13147           0 :         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
   13148             :         /* Substitution depends on current time, so better test the underlying
   13149             :            formatting function. At least covers %t. */
   13150           0 :         ok &= timesubst_test();
   13151             : 
   13152             :         /* Different captialization rules in sub_basic... */
   13153             : 
   13154           0 :         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
   13155           0 :                        "blaDOM") == 0);
   13156             : 
   13157           0 :         return ok;
   13158             : }
   13159             : 
   13160           0 : static bool run_local_base64(int dummy)
   13161             : {
   13162             :         int i;
   13163           0 :         bool ret = true;
   13164             : 
   13165           0 :         for (i=1; i<2000; i++) {
   13166             :                 DATA_BLOB blob1, blob2;
   13167             :                 char *b64;
   13168             : 
   13169           0 :                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
   13170           0 :                 blob1.length = i;
   13171           0 :                 generate_random_buffer(blob1.data, blob1.length);
   13172             : 
   13173           0 :                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
   13174           0 :                 if (b64 == NULL) {
   13175           0 :                         d_fprintf(stderr, "base64_encode_data_blob failed "
   13176             :                                   "for %d bytes\n", i);
   13177           0 :                         ret = false;
   13178             :                 }
   13179           0 :                 blob2 = base64_decode_data_blob(b64);
   13180           0 :                 TALLOC_FREE(b64);
   13181             : 
   13182           0 :                 if (data_blob_cmp(&blob1, &blob2)) {
   13183           0 :                         d_fprintf(stderr, "data_blob_cmp failed for %d "
   13184             :                                   "bytes\n", i);
   13185           0 :                         ret = false;
   13186             :                 }
   13187           0 :                 TALLOC_FREE(blob1.data);
   13188           0 :                 data_blob_free(&blob2);
   13189             :         }
   13190           0 :         return ret;
   13191             : }
   13192             : 
   13193           0 : static void parse_fn(const struct gencache_timeout *t,
   13194             :                      DATA_BLOB blob,
   13195             :                      void *private_data)
   13196             : {
   13197           0 :         return;
   13198             : }
   13199             : 
   13200           0 : static bool run_local_gencache(int dummy)
   13201             : {
   13202             :         char *val;
   13203             :         time_t tm;
   13204             :         DATA_BLOB blob;
   13205             :         char v;
   13206             :         struct memcache *mem;
   13207             :         int i;
   13208             : 
   13209           0 :         mem = memcache_init(NULL, 0);
   13210           0 :         if (mem == NULL) {
   13211           0 :                 d_printf("%s: memcache_init failed\n", __location__);
   13212           0 :                 return false;
   13213             :         }
   13214           0 :         memcache_set_global(mem);
   13215             : 
   13216           0 :         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
   13217           0 :                 d_printf("%s: gencache_set() failed\n", __location__);
   13218           0 :                 return False;
   13219             :         }
   13220             : 
   13221           0 :         if (!gencache_get("foo", NULL, NULL, NULL)) {
   13222           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13223           0 :                 return False;
   13224             :         }
   13225             : 
   13226           0 :         for (i=0; i<1000000; i++) {
   13227           0 :                 gencache_parse("foo", parse_fn, NULL);
   13228             :         }
   13229             : 
   13230           0 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13231           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13232           0 :                 return False;
   13233             :         }
   13234           0 :         TALLOC_FREE(val);
   13235             : 
   13236           0 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13237           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13238           0 :                 return False;
   13239             :         }
   13240             : 
   13241           0 :         if (strcmp(val, "bar") != 0) {
   13242           0 :                 d_printf("%s: gencache_get() returned %s, expected %s\n",
   13243             :                          __location__, val, "bar");
   13244           0 :                 TALLOC_FREE(val);
   13245           0 :                 return False;
   13246             :         }
   13247             : 
   13248           0 :         TALLOC_FREE(val);
   13249             : 
   13250           0 :         if (!gencache_del("foo")) {
   13251           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13252           0 :                 return False;
   13253             :         }
   13254           0 :         if (gencache_del("foo")) {
   13255           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13256             :                          __location__);
   13257           0 :                 return False;
   13258             :         }
   13259             : 
   13260           0 :         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
   13261           0 :                 d_printf("%s: gencache_get() on deleted entry "
   13262             :                          "succeeded\n", __location__);
   13263           0 :                 return False;
   13264             :         }
   13265             : 
   13266           0 :         blob = data_blob_string_const_null("bar");
   13267           0 :         tm = time(NULL) + 60;
   13268             : 
   13269           0 :         if (!gencache_set_data_blob("foo", blob, tm)) {
   13270           0 :                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
   13271           0 :                 return False;
   13272             :         }
   13273             : 
   13274           0 :         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13275           0 :                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
   13276           0 :                 return False;
   13277             :         }
   13278             : 
   13279           0 :         if (strcmp((const char *)blob.data, "bar") != 0) {
   13280           0 :                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
   13281           0 :                          __location__, (const char *)blob.data, "bar");
   13282           0 :                 data_blob_free(&blob);
   13283           0 :                 return False;
   13284             :         }
   13285             : 
   13286           0 :         data_blob_free(&blob);
   13287             : 
   13288           0 :         if (!gencache_del("foo")) {
   13289           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13290           0 :                 return False;
   13291             :         }
   13292           0 :         if (gencache_del("foo")) {
   13293           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13294             :                          __location__);
   13295           0 :                 return False;
   13296             :         }
   13297             : 
   13298           0 :         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13299           0 :                 d_printf("%s: gencache_get_data_blob() on deleted entry "
   13300             :                          "succeeded\n", __location__);
   13301           0 :                 return False;
   13302             :         }
   13303             : 
   13304           0 :         v = 1;
   13305           0 :         blob.data = (uint8_t *)&v;
   13306           0 :         blob.length = sizeof(v);
   13307             : 
   13308           0 :         if (!gencache_set_data_blob("blob", blob, tm)) {
   13309           0 :                 d_printf("%s: gencache_set_data_blob() failed\n",
   13310             :                          __location__);
   13311           0 :                 return false;
   13312             :         }
   13313           0 :         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
   13314           0 :                 d_printf("%s: gencache_get succeeded\n", __location__);
   13315           0 :                 return false;
   13316             :         }
   13317             : 
   13318           0 :         return True;
   13319             : }
   13320             : 
   13321           0 : static bool rbt_testflags(struct db_context *db, const char *key,
   13322             :                           const char *value)
   13323             : {
   13324           0 :         bool ret = false;
   13325             :         NTSTATUS status;
   13326             :         struct db_record *rec;
   13327             : 
   13328           0 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13329           0 :         if (rec == NULL) {
   13330           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13331           0 :                 goto done;
   13332             :         }
   13333             : 
   13334           0 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13335           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   13336           0 :                 d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
   13337             :                           nt_errstr(status));
   13338           0 :                 goto done;
   13339             :         }
   13340             : 
   13341           0 :         status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
   13342             :                                      TDB_INSERT);
   13343           0 :         if (!NT_STATUS_IS_OK(status)) {
   13344           0 :                 d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
   13345             :                           nt_errstr(status));
   13346           0 :                 goto done;
   13347             :         }
   13348             : 
   13349           0 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
   13350           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
   13351           0 :                 d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
   13352             :                           nt_errstr(status));
   13353           0 :                 goto done;
   13354             :         }
   13355             : 
   13356           0 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13357           0 :         if (!NT_STATUS_IS_OK(status)) {
   13358           0 :                 d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
   13359             :                           nt_errstr(status));
   13360           0 :                 goto done;
   13361             :         }
   13362             : 
   13363           0 :         ret = true;
   13364           0 : done:
   13365           0 :         TALLOC_FREE(rec);
   13366           0 :         return ret;
   13367             : }
   13368             : 
   13369           0 : static bool rbt_testval(struct db_context *db, const char *key,
   13370             :                         const char *value)
   13371             : {
   13372             :         struct db_record *rec;
   13373           0 :         TDB_DATA data = string_tdb_data(value);
   13374           0 :         bool ret = false;
   13375             :         NTSTATUS status;
   13376             :         TDB_DATA dbvalue;
   13377             : 
   13378           0 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13379           0 :         if (rec == NULL) {
   13380           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13381           0 :                 goto done;
   13382             :         }
   13383           0 :         status = dbwrap_record_store(rec, data, 0);
   13384           0 :         if (!NT_STATUS_IS_OK(status)) {
   13385           0 :                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
   13386           0 :                 goto done;
   13387             :         }
   13388           0 :         TALLOC_FREE(rec);
   13389             : 
   13390           0 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13391           0 :         if (rec == NULL) {
   13392           0 :                 d_fprintf(stderr, "second fetch_locked failed\n");
   13393           0 :                 goto done;
   13394             :         }
   13395             : 
   13396           0 :         dbvalue = dbwrap_record_get_value(rec);
   13397           0 :         if ((dbvalue.dsize != data.dsize)
   13398           0 :             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
   13399           0 :                 d_fprintf(stderr, "Got wrong data back\n");
   13400           0 :                 goto done;
   13401             :         }
   13402             : 
   13403           0 :         ret = true;
   13404           0 :  done:
   13405           0 :         TALLOC_FREE(rec);
   13406           0 :         return ret;
   13407             : }
   13408             : 
   13409           0 : static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
   13410             : {
   13411           0 :         int *count2 = (int *)private_data;
   13412           0 :         (*count2)++;
   13413           0 :         return 0;
   13414             : }
   13415             : 
   13416           0 : static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
   13417             : {
   13418           0 :         int *count2 = (int *)private_data;
   13419           0 :         (*count2)++;
   13420           0 :         dbwrap_record_delete(rec);
   13421           0 :         return 0;
   13422             : }
   13423             : 
   13424           0 : static bool run_local_rbtree(int dummy)
   13425             : {
   13426             :         struct db_context *db;
   13427           0 :         bool ret = false;
   13428             :         int i;
   13429             :         NTSTATUS status;
   13430           0 :         int count = 0;
   13431           0 :         int count2 = 0;
   13432             : 
   13433           0 :         db = db_open_rbt(NULL);
   13434             : 
   13435           0 :         if (db == NULL) {
   13436           0 :                 d_fprintf(stderr, "db_open_rbt failed\n");
   13437           0 :                 return false;
   13438             :         }
   13439             : 
   13440           0 :         if (!rbt_testflags(db, "firstkey", "firstval")) {
   13441           0 :                 goto done;
   13442             :         }
   13443             : 
   13444           0 :         for (i = 0; i < 999; i++) {
   13445             :                 char key[sizeof("key-9223372036854775807")];
   13446             :                 char value[sizeof("value-9223372036854775807")];
   13447             : 
   13448           0 :                 snprintf(key, sizeof(key), "key%ld", random());
   13449           0 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13450             : 
   13451           0 :                 if (!rbt_testval(db, key, value)) {
   13452           0 :                         goto done;
   13453             :                 }
   13454             : 
   13455           0 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13456             : 
   13457           0 :                 if (!rbt_testval(db, key, value)) {
   13458           0 :                         goto done;
   13459             :                 }
   13460             :         }
   13461             : 
   13462           0 :         ret = true;
   13463           0 :         count = 0; count2 = 0;
   13464           0 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13465             :                                       &count2, &count);
   13466           0 :         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13467           0 :         if ((count != count2) || (count != 1000)) {
   13468           0 :                 ret = false;
   13469             :         }
   13470           0 :         count = 0; count2 = 0;
   13471           0 :         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
   13472             :                                  &count2, &count);
   13473           0 :         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13474           0 :         if ((count != count2) || (count != 1000)) {
   13475           0 :                 ret = false;
   13476             :         }
   13477           0 :         count = 0; count2 = 0;
   13478           0 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13479             :                                       &count2, &count);
   13480           0 :         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13481           0 :         if ((count != count2) || (count != 0)) {
   13482           0 :                 ret = false;
   13483             :         }
   13484             : 
   13485           0 :  done:
   13486           0 :         TALLOC_FREE(db);
   13487           0 :         return ret;
   13488             : }
   13489             : 
   13490             : 
   13491             : /*
   13492             :   local test for character set functions
   13493             : 
   13494             :   This is a very simple test for the functionality in convert_string_error()
   13495             :  */
   13496           0 : static bool run_local_convert_string(int dummy)
   13497             : {
   13498           0 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   13499           0 :         const char *test_strings[2] = { "March", "M\303\244rz" };
   13500             :         char dst[7];
   13501             :         int i;
   13502             : 
   13503           0 :         for (i=0; i<2; i++) {
   13504           0 :                 const char *str = test_strings[i];
   13505           0 :                 int len = strlen(str);
   13506             :                 size_t converted_size;
   13507             :                 bool ret;
   13508             : 
   13509           0 :                 memset(dst, 'X', sizeof(dst));
   13510             : 
   13511             :                 /* first try with real source length */
   13512           0 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13513             :                                            str, len,
   13514             :                                            dst, sizeof(dst),
   13515             :                                            &converted_size);
   13516           0 :                 if (ret != true) {
   13517           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13518           0 :                         goto failed;
   13519             :                 }
   13520             : 
   13521           0 :                 if (converted_size != len) {
   13522           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13523             :                                   str, len, (int)converted_size);
   13524           0 :                         goto failed;
   13525             :                 }
   13526             : 
   13527           0 :                 if (strncmp(str, dst, converted_size) != 0) {
   13528           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13529           0 :                         goto failed;
   13530             :                 }
   13531             : 
   13532           0 :                 if (strlen(str) != converted_size) {
   13533           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13534           0 :                                   (int)strlen(str), (int)converted_size);
   13535           0 :                         goto failed;
   13536             :                 }
   13537             : 
   13538           0 :                 if (dst[converted_size] != 'X') {
   13539           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13540           0 :                         goto failed;
   13541             :                 }
   13542             : 
   13543             :                 /* now with srclen==-1, this causes the nul to be
   13544             :                  * converted too */
   13545           0 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13546             :                                            str, -1,
   13547             :                                            dst, sizeof(dst),
   13548             :                                            &converted_size);
   13549           0 :                 if (ret != true) {
   13550           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13551           0 :                         goto failed;
   13552             :                 }
   13553             : 
   13554           0 :                 if (converted_size != len+1) {
   13555           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13556             :                                   str, len, (int)converted_size);
   13557           0 :                         goto failed;
   13558             :                 }
   13559             : 
   13560           0 :                 if (strncmp(str, dst, converted_size) != 0) {
   13561           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13562           0 :                         goto failed;
   13563             :                 }
   13564             : 
   13565           0 :                 if (len+1 != converted_size) {
   13566           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13567             :                                   len+1, (int)converted_size);
   13568           0 :                         goto failed;
   13569             :                 }
   13570             : 
   13571           0 :                 if (dst[converted_size] != 'X') {
   13572           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13573           0 :                         goto failed;
   13574             :                 }
   13575             : 
   13576             :         }
   13577             : 
   13578             : 
   13579           0 :         TALLOC_FREE(tmp_ctx);
   13580           0 :         return true;
   13581           0 : failed:
   13582           0 :         TALLOC_FREE(tmp_ctx);
   13583           0 :         return false;
   13584             : }
   13585             : 
   13586           0 : static bool run_local_string_to_sid(int dummy) {
   13587             :         struct dom_sid sid;
   13588             : 
   13589           0 :         if (string_to_sid(&sid, "S--1-5-32-545")) {
   13590           0 :                 printf("allowing S--1-5-32-545\n");
   13591           0 :                 return false;
   13592             :         }
   13593           0 :         if (string_to_sid(&sid, "S-1-5-32-+545")) {
   13594           0 :                 printf("allowing S-1-5-32-+545\n");
   13595           0 :                 return false;
   13596             :         }
   13597           0 :         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")) {
   13598           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");
   13599           0 :                 return false;
   13600             :         }
   13601           0 :         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
   13602           0 :                 printf("allowing S-1-5-32-545-abc\n");
   13603           0 :                 return false;
   13604             :         }
   13605           0 :         if (string_to_sid(&sid, "S-300-5-32-545")) {
   13606           0 :                 printf("allowing S-300-5-32-545\n");
   13607           0 :                 return false;
   13608             :         }
   13609           0 :         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
   13610           0 :                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
   13611           0 :                 return false;
   13612             :         }
   13613           0 :         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
   13614           0 :                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
   13615           0 :                 return false;
   13616             :         }
   13617           0 :         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
   13618           0 :                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
   13619           0 :                 return false;
   13620             :         }
   13621           0 :         if (!string_to_sid(&sid, "S-1-5-32-545")) {
   13622           0 :                 printf("could not parse S-1-5-32-545\n");
   13623           0 :                 return false;
   13624             :         }
   13625           0 :         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
   13626             :                 struct dom_sid_buf buf;
   13627           0 :                 printf("mis-parsed S-1-5-32-545 as %s\n",
   13628             :                        dom_sid_str_buf(&sid, &buf));
   13629           0 :                 return false;
   13630             :         }
   13631           0 :         return true;
   13632             : }
   13633             : 
   13634           0 : static bool sid_to_string_test(const char *expected) {
   13635             :         char *str;
   13636           0 :         bool res = true;
   13637             :         struct dom_sid sid;
   13638             : 
   13639           0 :         if (!string_to_sid(&sid, expected)) {
   13640           0 :                 printf("could not parse %s\n", expected);
   13641           0 :                 return false;
   13642             :         }
   13643             : 
   13644           0 :         str = dom_sid_string(NULL, &sid);
   13645           0 :         if (strcmp(str, expected)) {
   13646           0 :                 printf("Comparison failed (%s != %s)\n", str, expected);
   13647           0 :                 res = false;
   13648             :         }
   13649           0 :         TALLOC_FREE(str);
   13650           0 :         return res;
   13651             : }
   13652             : 
   13653           0 : static bool run_local_sid_to_string(int dummy) {
   13654           0 :         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
   13655           0 :                 return false;
   13656           0 :         if (!sid_to_string_test("S-1-545"))
   13657           0 :                 return false;
   13658           0 :         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
   13659           0 :                 return false;
   13660           0 :         return true;
   13661             : }
   13662             : 
   13663           0 : static bool run_local_binary_to_sid(int dummy) {
   13664             :         ssize_t ret;
   13665           0 :         struct dom_sid *sid = talloc(NULL, struct dom_sid);
   13666             :         static const uint8_t good_binary_sid[] = {
   13667             :                 0x1, /* revision number */
   13668             :                 15, /* num auths */
   13669             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13670             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13671             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13672             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13673             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13674             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13675             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13676             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13677             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13678             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13679             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13680             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13681             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13682             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13683             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13684             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13685             :         };
   13686             : 
   13687             :         static const uint8_t long_binary_sid[] = {
   13688             :                 0x1, /* revision number */
   13689             :                 15, /* num auths */
   13690             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13691             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13692             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13693             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13694             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13695             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13696             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13697             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13698             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13699             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13700             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13701             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13702             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13703             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13704             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13705             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13706             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13707             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13708             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13709             :         };
   13710             : 
   13711             :         static const uint8_t long_binary_sid2[] = {
   13712             :                 0x1, /* revision number */
   13713             :                 32, /* num auths */
   13714             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13715             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13716             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13717             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13718             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13719             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13720             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13721             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13722             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13723             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13724             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13725             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13726             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13727             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13728             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13729             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13730             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13731             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13732             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13733             :                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
   13734             :                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
   13735             :                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
   13736             :                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
   13737             :                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
   13738             :                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
   13739             :                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
   13740             :                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
   13741             :                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
   13742             :                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
   13743             :                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
   13744             :                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
   13745             :                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
   13746             :                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
   13747             :         };
   13748             : 
   13749           0 :         ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
   13750           0 :         if (ret == -1) {
   13751           0 :                 return false;
   13752             :         }
   13753           0 :         ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
   13754           0 :         if (ret != -1) {
   13755           0 :                 return false;
   13756             :         }
   13757           0 :         ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
   13758           0 :         if (ret != -1) {
   13759           0 :                 return false;
   13760             :         }
   13761           0 :         return true;
   13762             : }
   13763             : 
   13764             : /* Split a path name into filename and stream name components. Canonicalise
   13765             :  * such that an implicit $DATA token is always explicit.
   13766             :  *
   13767             :  * The "specification" of this function can be found in the
   13768             :  * run_local_stream_name() function in torture.c, I've tried those
   13769             :  * combinations against a W2k3 server.
   13770             :  */
   13771             : 
   13772           0 : static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
   13773             :                                        char **pbase, char **pstream)
   13774             : {
   13775           0 :         char *base = NULL;
   13776           0 :         char *stream = NULL;
   13777             :         char *sname; /* stream name */
   13778             :         const char *stype; /* stream type */
   13779             : 
   13780           0 :         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
   13781             : 
   13782           0 :         sname = strchr_m(fname, ':');
   13783             : 
   13784           0 :         if (sname == NULL) {
   13785           0 :                 if (pbase != NULL) {
   13786           0 :                         base = talloc_strdup(mem_ctx, fname);
   13787           0 :                         NT_STATUS_HAVE_NO_MEMORY(base);
   13788             :                 }
   13789           0 :                 goto done;
   13790             :         }
   13791             : 
   13792           0 :         if (pbase != NULL) {
   13793           0 :                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
   13794           0 :                 NT_STATUS_HAVE_NO_MEMORY(base);
   13795             :         }
   13796             : 
   13797           0 :         sname += 1;
   13798             : 
   13799           0 :         stype = strchr_m(sname, ':');
   13800             : 
   13801           0 :         if (stype == NULL) {
   13802           0 :                 sname = talloc_strdup(mem_ctx, sname);
   13803           0 :                 stype = "$DATA";
   13804             :         }
   13805             :         else {
   13806           0 :                 if (strcasecmp_m(stype, ":$DATA") != 0) {
   13807             :                         /*
   13808             :                          * If there is an explicit stream type, so far we only
   13809             :                          * allow $DATA. Is there anything else allowed? -- vl
   13810             :                          */
   13811           0 :                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
   13812           0 :                         TALLOC_FREE(base);
   13813           0 :                         return NT_STATUS_OBJECT_NAME_INVALID;
   13814             :                 }
   13815           0 :                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
   13816           0 :                 stype += 1;
   13817             :         }
   13818             : 
   13819           0 :         if (sname == NULL) {
   13820           0 :                 TALLOC_FREE(base);
   13821           0 :                 return NT_STATUS_NO_MEMORY;
   13822             :         }
   13823             : 
   13824           0 :         if (sname[0] == '\0') {
   13825             :                 /*
   13826             :                  * no stream name, so no stream
   13827             :                  */
   13828           0 :                 goto done;
   13829             :         }
   13830             : 
   13831           0 :         if (pstream != NULL) {
   13832           0 :                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
   13833           0 :                 if (stream == NULL) {
   13834           0 :                         TALLOC_FREE(sname);
   13835           0 :                         TALLOC_FREE(base);
   13836           0 :                         return NT_STATUS_NO_MEMORY;
   13837             :                 }
   13838             :                 /*
   13839             :                  * upper-case the type field
   13840             :                  */
   13841           0 :                 (void)strupper_m(strchr_m(stream, ':')+1);
   13842             :         }
   13843             : 
   13844           0 :  done:
   13845           0 :         if (pbase != NULL) {
   13846           0 :                 *pbase = base;
   13847             :         }
   13848           0 :         if (pstream != NULL) {
   13849           0 :                 *pstream = stream;
   13850             :         }
   13851           0 :         return NT_STATUS_OK;
   13852             : }
   13853             : 
   13854           0 : static bool test_stream_name(const char *fname, const char *expected_base,
   13855             :                              const char *expected_stream,
   13856             :                              NTSTATUS expected_status)
   13857             : {
   13858             :         NTSTATUS status;
   13859           0 :         char *base = NULL;
   13860           0 :         char *stream = NULL;
   13861             : 
   13862           0 :         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
   13863           0 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   13864           0 :                 goto error;
   13865             :         }
   13866             : 
   13867           0 :         if (!NT_STATUS_IS_OK(status)) {
   13868           0 :                 return true;
   13869             :         }
   13870             : 
   13871           0 :         if (base == NULL) goto error;
   13872             : 
   13873           0 :         if (strcmp(expected_base, base) != 0) goto error;
   13874             : 
   13875           0 :         if ((expected_stream != NULL) && (stream == NULL)) goto error;
   13876           0 :         if ((expected_stream == NULL) && (stream != NULL)) goto error;
   13877             : 
   13878           0 :         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
   13879           0 :                 goto error;
   13880             : 
   13881           0 :         TALLOC_FREE(base);
   13882           0 :         TALLOC_FREE(stream);
   13883           0 :         return true;
   13884             : 
   13885           0 :  error:
   13886           0 :         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
   13887             :                   fname, expected_base ? expected_base : "<NULL>",
   13888             :                   expected_stream ? expected_stream : "<NULL>",
   13889             :                   nt_errstr(expected_status));
   13890           0 :         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
   13891           0 :                   base ? base : "<NULL>", stream ? stream : "<NULL>",
   13892             :                   nt_errstr(status));
   13893           0 :         TALLOC_FREE(base);
   13894           0 :         TALLOC_FREE(stream);
   13895           0 :         return false;
   13896             : }
   13897             : 
   13898           0 : static bool run_local_stream_name(int dummy)
   13899             : {
   13900           0 :         bool ret = true;
   13901             : 
   13902           0 :         ret &= test_stream_name(
   13903           0 :                 "bla", "bla", NULL, NT_STATUS_OK);
   13904           0 :         ret &= test_stream_name(
   13905           0 :                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
   13906           0 :         ret &= test_stream_name(
   13907           0 :                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13908           0 :         ret &= test_stream_name(
   13909           0 :                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13910           0 :         ret &= test_stream_name(
   13911           0 :                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13912           0 :         ret &= test_stream_name(
   13913           0 :                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
   13914           0 :         ret &= test_stream_name(
   13915           0 :                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
   13916           0 :         ret &= test_stream_name(
   13917           0 :                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
   13918             : 
   13919           0 :         return ret;
   13920             : }
   13921             : 
   13922           0 : static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
   13923             : {
   13924           0 :         if (a.length != b.length) {
   13925           0 :                 printf("a.length=%d != b.length=%d\n",
   13926           0 :                        (int)a.length, (int)b.length);
   13927           0 :                 return false;
   13928             :         }
   13929           0 :         if (memcmp(a.data, b.data, a.length) != 0) {
   13930           0 :                 printf("a.data and b.data differ\n");
   13931           0 :                 return false;
   13932             :         }
   13933           0 :         return true;
   13934             : }
   13935             : 
   13936           0 : static bool run_local_memcache(int dummy)
   13937             : {
   13938             :         struct memcache *cache;
   13939             :         DATA_BLOB k1, k2, k3, k4, k5;
   13940             :         DATA_BLOB d1, d3;
   13941             :         DATA_BLOB v1, v3;
   13942             : 
   13943             :         TALLOC_CTX *mem_ctx;
   13944           0 :         char *ptr1 = NULL;
   13945           0 :         char *ptr2 = NULL;
   13946           0 :         char *ptr3 = NULL;
   13947             : 
   13948             :         char *str1, *str2;
   13949             :         size_t size1, size2;
   13950           0 :         bool ret = false;
   13951             : 
   13952           0 :         mem_ctx = talloc_init("foo");
   13953           0 :         if (mem_ctx == NULL) {
   13954           0 :                 return false;
   13955             :         }
   13956             : 
   13957             :         /* STAT_CACHE TESTS */
   13958             : 
   13959           0 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   13960             : 
   13961           0 :         if (cache == NULL) {
   13962           0 :                 printf("memcache_init failed\n");
   13963           0 :                 return false;
   13964             :         }
   13965             : 
   13966           0 :         d1 = data_blob_const("d1", 2);
   13967           0 :         d3 = data_blob_const("d3", 2);
   13968             : 
   13969           0 :         k1 = data_blob_const("d1", 2);
   13970           0 :         k2 = data_blob_const("d2", 2);
   13971           0 :         k3 = data_blob_const("d3", 2);
   13972           0 :         k4 = data_blob_const("d4", 2);
   13973           0 :         k5 = data_blob_const("d5", 2);
   13974             : 
   13975           0 :         memcache_add(cache, STAT_CACHE, k1, d1);
   13976             : 
   13977           0 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
   13978           0 :                 printf("could not find k1\n");
   13979           0 :                 return false;
   13980             :         }
   13981           0 :         if (!data_blob_equal(d1, v1)) {
   13982           0 :                 return false;
   13983             :         }
   13984             : 
   13985           0 :         memcache_add(cache, STAT_CACHE, k1, d3);
   13986             : 
   13987           0 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
   13988           0 :                 printf("could not find replaced k1\n");
   13989           0 :                 return false;
   13990             :         }
   13991           0 :         if (!data_blob_equal(d3, v3)) {
   13992           0 :                 return false;
   13993             :         }
   13994             : 
   13995           0 :         TALLOC_FREE(cache);
   13996             : 
   13997             :         /* GETWD_CACHE TESTS */
   13998           0 :         str1 = talloc_strdup(mem_ctx, "string1");
   13999           0 :         if (str1 == NULL) {
   14000           0 :                 return false;
   14001             :         }
   14002           0 :         ptr2 = str1; /* Keep an alias for comparison. */
   14003             : 
   14004           0 :         str2 = talloc_strdup(mem_ctx, "string2");
   14005           0 :         if (str2 == NULL) {
   14006           0 :                 return false;
   14007             :         }
   14008             : 
   14009           0 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14010           0 :         if (cache == NULL) {
   14011           0 :                 printf("memcache_init failed\n");
   14012           0 :                 return false;
   14013             :         }
   14014             : 
   14015           0 :         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
   14016             :         /* str1 == NULL now. */
   14017           0 :         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14018           0 :         if (ptr1 == NULL) {
   14019           0 :                 printf("could not find k2\n");
   14020           0 :                 return false;
   14021             :         }
   14022           0 :         if (ptr1 != ptr2) {
   14023           0 :                 printf("fetch of k2 got wrong string\n");
   14024           0 :                 return false;
   14025             :         }
   14026             : 
   14027             :         /* Add a blob to ensure k2 gets purged. */
   14028           0 :         d3 = data_blob_talloc_zero(mem_ctx, 180);
   14029           0 :         memcache_add(cache, STAT_CACHE, k3, d3);
   14030             : 
   14031           0 :         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14032           0 :         if (ptr2 != NULL) {
   14033           0 :                 printf("Did find k2, should have been purged\n");
   14034           0 :                 return false;
   14035             :         }
   14036             : 
   14037             :         /*
   14038             :          * Test that talloc size also is accounted in memcache and
   14039             :          * causes purge of other object.
   14040             :          */
   14041             : 
   14042           0 :         str1 = talloc_zero_size(mem_ctx, 100);
   14043           0 :         str2 = talloc_zero_size(mem_ctx, 100);
   14044             : 
   14045           0 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14046           0 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
   14047             : 
   14048           0 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14049           0 :         if (ptr3 != NULL) {
   14050           0 :                 printf("Did find k4, should have been purged\n");
   14051           0 :                 return false;
   14052             :         }
   14053             : 
   14054             :         /*
   14055             :          * Test that adding a duplicate non-talloced
   14056             :          * key/value on top of a talloced key/value takes account
   14057             :          * of the talloc_freed value size.
   14058             :          */
   14059           0 :         TALLOC_FREE(cache);
   14060           0 :         TALLOC_FREE(mem_ctx);
   14061             : 
   14062           0 :         mem_ctx = talloc_init("key_replace");
   14063           0 :         if (mem_ctx == NULL) {
   14064           0 :                 return false;
   14065             :         }
   14066             : 
   14067           0 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14068           0 :         if (cache == NULL) {
   14069           0 :                 return false;
   14070             :         }
   14071             : 
   14072             :         /*
   14073             :          * Add a 100 byte talloced string. This will
   14074             :          * store a (4 or 8 byte) pointer and record the
   14075             :          * total talloced size.
   14076             :          */
   14077           0 :         str1 = talloc_zero_size(mem_ctx, 100);
   14078           0 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14079             :         /*
   14080             :          * Now overwrite with a small talloced
   14081             :          * value. This should fit in the existing size
   14082             :          * and the total talloced size should be removed
   14083             :          * from the cache size.
   14084             :          */
   14085           0 :         str1 = talloc_zero_size(mem_ctx, 2);
   14086           0 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14087             :         /*
   14088             :          * Now store a 20 byte string. If the
   14089             :          * total talloced size wasn't accounted for
   14090             :          * and removed in the overwrite, then this
   14091             :          * will evict k4.
   14092             :          */
   14093           0 :         str2 = talloc_zero_size(mem_ctx, 20);
   14094           0 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
   14095             : 
   14096           0 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14097           0 :         if (ptr3 == NULL) {
   14098           0 :                 printf("Did not find k4, should not have been purged\n");
   14099           0 :                 return false;
   14100             :         }
   14101             : 
   14102           0 :         TALLOC_FREE(cache);
   14103           0 :         TALLOC_FREE(mem_ctx);
   14104             : 
   14105           0 :         mem_ctx = talloc_init("foo");
   14106           0 :         if (mem_ctx == NULL) {
   14107           0 :                 return false;
   14108             :         }
   14109             : 
   14110           0 :         cache = memcache_init(NULL, 0);
   14111           0 :         if (cache == NULL) {
   14112           0 :                 return false;
   14113             :         }
   14114             : 
   14115           0 :         str1 = talloc_strdup(mem_ctx, "string1");
   14116           0 :         if (str1 == NULL) {
   14117           0 :                 return false;
   14118             :         }
   14119           0 :         str2 = talloc_strdup(mem_ctx, "string2");
   14120           0 :         if (str2 == NULL) {
   14121           0 :                 return false;
   14122             :         }
   14123           0 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14124             :                             data_blob_string_const("torture"), &str1);
   14125           0 :         size1 = talloc_total_size(cache);
   14126             : 
   14127           0 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14128             :                             data_blob_string_const("torture"), &str2);
   14129           0 :         size2 = talloc_total_size(cache);
   14130             : 
   14131           0 :         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
   14132             : 
   14133           0 :         if (size2 > size1) {
   14134           0 :                 printf("memcache leaks memory!\n");
   14135           0 :                 goto fail;
   14136             :         }
   14137             : 
   14138           0 :         ret = true;
   14139           0 :  fail:
   14140           0 :         TALLOC_FREE(cache);
   14141           0 :         return ret;
   14142             : }
   14143             : 
   14144         200 : static void wbclient_done(struct tevent_req *req)
   14145             : {
   14146             :         wbcErr wbc_err;
   14147             :         struct winbindd_response *wb_resp;
   14148         200 :         int *i = (int *)tevent_req_callback_data_void(req);
   14149             : 
   14150         200 :         wbc_err = wb_trans_recv(req, req, &wb_resp);
   14151         200 :         TALLOC_FREE(req);
   14152         200 :         *i += 1;
   14153         200 :         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
   14154         200 : }
   14155             : 
   14156           2 : static bool run_wbclient_multi_ping(int dummy)
   14157             : {
   14158             :         struct tevent_context *ev;
   14159             :         struct wb_context **wb_ctx;
   14160             :         struct winbindd_request wb_req;
   14161           2 :         bool result = false;
   14162             :         int i, j;
   14163             : 
   14164           2 :         BlockSignals(True, SIGPIPE);
   14165             : 
   14166           2 :         ev = tevent_context_init(talloc_tos());
   14167           2 :         if (ev == NULL) {
   14168           0 :                 goto fail;
   14169             :         }
   14170             : 
   14171           2 :         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
   14172           2 :         if (wb_ctx == NULL) {
   14173           0 :                 goto fail;
   14174             :         }
   14175             : 
   14176           2 :         ZERO_STRUCT(wb_req);
   14177           2 :         wb_req.cmd = WINBINDD_PING;
   14178             : 
   14179           2 :         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
   14180             : 
   14181           4 :         for (i=0; i<torture_nprocs; i++) {
   14182           2 :                 wb_ctx[i] = wb_context_init(ev, NULL);
   14183           2 :                 if (wb_ctx[i] == NULL) {
   14184           0 :                         goto fail;
   14185             :                 }
   14186         202 :                 for (j=0; j<torture_numops; j++) {
   14187             :                         struct tevent_req *req;
   14188         200 :                         req = wb_trans_send(ev, ev, wb_ctx[i],
   14189         200 :                                             (j % 2) == 0, &wb_req);
   14190         200 :                         if (req == NULL) {
   14191           0 :                                 goto fail;
   14192             :                         }
   14193         200 :                         tevent_req_set_callback(req, wbclient_done, &i);
   14194             :                 }
   14195             :         }
   14196             : 
   14197           2 :         i = 0;
   14198             : 
   14199         819 :         while (i < torture_nprocs * torture_numops) {
   14200         816 :                 tevent_loop_once(ev);
   14201             :         }
   14202             : 
   14203           2 :         result = true;
   14204           2 :  fail:
   14205           2 :         TALLOC_FREE(ev);
   14206           2 :         return result;
   14207             : }
   14208             : 
   14209           0 : static bool dbtrans_inc(struct db_context *db)
   14210             : {
   14211             :         struct db_record *rec;
   14212             :         uint32_t val;
   14213           0 :         bool ret = false;
   14214             :         NTSTATUS status;
   14215             :         TDB_DATA value;
   14216             : 
   14217           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14218           0 :         if (rec == NULL) {
   14219           0 :                 printf(__location__ "fetch_lock failed\n");
   14220           0 :                 return false;
   14221             :         }
   14222             : 
   14223           0 :         value = dbwrap_record_get_value(rec);
   14224             : 
   14225           0 :         if (value.dsize != sizeof(uint32_t)) {
   14226           0 :                 printf(__location__ "value.dsize = %d\n",
   14227           0 :                        (int)value.dsize);
   14228           0 :                 goto fail;
   14229             :         }
   14230             : 
   14231           0 :         memcpy(&val, value.dptr, sizeof(val));
   14232           0 :         val += 1;
   14233             : 
   14234           0 :         status = dbwrap_record_store(
   14235             :                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
   14236           0 :         if (!NT_STATUS_IS_OK(status)) {
   14237           0 :                 printf(__location__ "store failed: %s\n",
   14238             :                        nt_errstr(status));
   14239           0 :                 goto fail;
   14240             :         }
   14241             : 
   14242           0 :         ret = true;
   14243           0 : fail:
   14244           0 :         TALLOC_FREE(rec);
   14245           0 :         return ret;
   14246             : }
   14247             : 
   14248           0 : static bool run_local_dbtrans(int dummy)
   14249             : {
   14250             :         struct db_context *db;
   14251             :         struct db_record *rec;
   14252             :         NTSTATUS status;
   14253             :         uint32_t initial;
   14254             :         int res;
   14255             :         TDB_DATA value;
   14256             : 
   14257           0 :         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
   14258             :                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
   14259             :                      DBWRAP_FLAG_NONE);
   14260           0 :         if (db == NULL) {
   14261           0 :                 printf("Could not open transtest.db\n");
   14262           0 :                 return false;
   14263             :         }
   14264             : 
   14265           0 :         res = dbwrap_transaction_start(db);
   14266           0 :         if (res != 0) {
   14267           0 :                 printf(__location__ "transaction_start failed\n");
   14268           0 :                 return false;
   14269             :         }
   14270             : 
   14271           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14272           0 :         if (rec == NULL) {
   14273           0 :                 printf(__location__ "fetch_lock failed\n");
   14274           0 :                 return false;
   14275             :         }
   14276             : 
   14277           0 :         value = dbwrap_record_get_value(rec);
   14278             : 
   14279           0 :         if (value.dptr == NULL) {
   14280           0 :                 initial = 0;
   14281           0 :                 status = dbwrap_record_store(
   14282             :                         rec, make_tdb_data((uint8_t *)&initial,
   14283             :                                            sizeof(initial)),
   14284             :                         0);
   14285           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14286           0 :                         printf(__location__ "store returned %s\n",
   14287             :                                nt_errstr(status));
   14288           0 :                         return false;
   14289             :                 }
   14290             :         }
   14291             : 
   14292           0 :         TALLOC_FREE(rec);
   14293             : 
   14294           0 :         res = dbwrap_transaction_commit(db);
   14295           0 :         if (res != 0) {
   14296           0 :                 printf(__location__ "transaction_commit failed\n");
   14297           0 :                 return false;
   14298             :         }
   14299             : 
   14300           0 :         while (true) {
   14301             :                 uint32_t val, val2;
   14302             :                 int i;
   14303             : 
   14304           0 :                 res = dbwrap_transaction_start(db);
   14305           0 :                 if (res != 0) {
   14306           0 :                         printf(__location__ "transaction_start failed\n");
   14307           0 :                         break;
   14308             :                 }
   14309             : 
   14310           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
   14311           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14312           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14313             :                                nt_errstr(status));
   14314           0 :                         break;
   14315             :                 }
   14316             : 
   14317           0 :                 for (i=0; i<10; i++) {
   14318           0 :                         if (!dbtrans_inc(db)) {
   14319           0 :                                 return false;
   14320             :                         }
   14321             :                 }
   14322             : 
   14323           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
   14324           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14325           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14326             :                                nt_errstr(status));
   14327           0 :                         break;
   14328             :                 }
   14329             : 
   14330           0 :                 if (val2 != val + 10) {
   14331           0 :                         printf(__location__ "val=%d, val2=%d\n",
   14332             :                                (int)val, (int)val2);
   14333           0 :                         break;
   14334             :                 }
   14335             : 
   14336           0 :                 printf("val2=%d\r", val2);
   14337             : 
   14338           0 :                 res = dbwrap_transaction_commit(db);
   14339           0 :                 if (res != 0) {
   14340           0 :                         printf(__location__ "transaction_commit failed\n");
   14341           0 :                         break;
   14342             :                 }
   14343             :         }
   14344             : 
   14345           0 :         TALLOC_FREE(db);
   14346           0 :         return true;
   14347             : }
   14348             : 
   14349             : /*
   14350             :  * Just a dummy test to be run under a debugger. There's no real way
   14351             :  * to inspect the tevent_poll specific function from outside of
   14352             :  * tevent_poll.c.
   14353             :  */
   14354             : 
   14355           0 : static bool run_local_tevent_poll(int dummy)
   14356             : {
   14357             :         struct tevent_context *ev;
   14358             :         struct tevent_fd *fd1, *fd2;
   14359           0 :         bool result = false;
   14360             : 
   14361           0 :         ev = tevent_context_init_byname(NULL, "poll");
   14362           0 :         if (ev == NULL) {
   14363           0 :                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
   14364           0 :                 goto fail;
   14365             :         }
   14366             : 
   14367           0 :         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
   14368           0 :         if (fd1 == NULL) {
   14369           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14370           0 :                 goto fail;
   14371             :         }
   14372           0 :         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
   14373           0 :         if (fd2 == NULL) {
   14374           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14375           0 :                 goto fail;
   14376             :         }
   14377           0 :         TALLOC_FREE(fd2);
   14378             : 
   14379           0 :         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
   14380           0 :         if (fd2 == NULL) {
   14381           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14382           0 :                 goto fail;
   14383             :         }
   14384             : 
   14385           0 :         result = true;
   14386           0 : fail:
   14387           0 :         TALLOC_FREE(ev);
   14388           0 :         return result;
   14389             : }
   14390             : 
   14391           0 : static bool run_local_hex_encode_buf(int dummy)
   14392             : {
   14393             :         char buf[17];
   14394             :         uint8_t src[8];
   14395             :         size_t i;
   14396             : 
   14397           0 :         for (i=0; i<sizeof(src); i++) {
   14398           0 :                 src[i] = i;
   14399             :         }
   14400           0 :         hex_encode_buf(buf, src, sizeof(src));
   14401           0 :         if (strcmp(buf, "0001020304050607") != 0) {
   14402           0 :                 return false;
   14403             :         }
   14404           0 :         hex_encode_buf(buf, NULL, 0);
   14405           0 :         if (buf[0] != '\0') {
   14406           0 :                 return false;
   14407             :         }
   14408           0 :         return true;
   14409             : }
   14410             : 
   14411             : static const char *remove_duplicate_addrs2_test_strings_vector[] = {
   14412             :         "0.0.0.0",
   14413             :         "::0",
   14414             :         "1.2.3.1",
   14415             :         "0.0.0.0",
   14416             :         "0.0.0.0",
   14417             :         "1.2.3.2",
   14418             :         "1.2.3.3",
   14419             :         "1.2.3.4",
   14420             :         "1.2.3.5",
   14421             :         "::0",
   14422             :         "1.2.3.6",
   14423             :         "1.2.3.7",
   14424             :         "::0",
   14425             :         "::0",
   14426             :         "::0",
   14427             :         "1.2.3.8",
   14428             :         "1.2.3.9",
   14429             :         "1.2.3.10",
   14430             :         "1.2.3.11",
   14431             :         "1.2.3.12",
   14432             :         "1.2.3.13",
   14433             :         "1001:1111:1111:1000:0:1111:1111:1111",
   14434             :         "1.2.3.1",
   14435             :         "1.2.3.2",
   14436             :         "1.2.3.3",
   14437             :         "1.2.3.12",
   14438             :         "::0",
   14439             :         "::0"
   14440             : };
   14441             : 
   14442             : static const char *remove_duplicate_addrs2_test_strings_result[] = {
   14443             :         "1.2.3.1",
   14444             :         "1.2.3.2",
   14445             :         "1.2.3.3",
   14446             :         "1.2.3.4",
   14447             :         "1.2.3.5",
   14448             :         "1.2.3.6",
   14449             :         "1.2.3.7",
   14450             :         "1.2.3.8",
   14451             :         "1.2.3.9",
   14452             :         "1.2.3.10",
   14453             :         "1.2.3.11",
   14454             :         "1.2.3.12",
   14455             :         "1.2.3.13",
   14456             :         "1001:1111:1111:1000:0:1111:1111:1111"
   14457             : };
   14458             : 
   14459           0 : static bool run_local_remove_duplicate_addrs2(int dummy)
   14460             : {
   14461             :         struct samba_sockaddr test_vector[28];
   14462             :         size_t count, i;
   14463             : 
   14464             :         /* Construct the sockaddr_storage test vector. */
   14465           0 :         for (i = 0; i < 28; i++) {
   14466             :                 struct addrinfo hints;
   14467           0 :                 struct addrinfo *res = NULL;
   14468             :                 int ret;
   14469             : 
   14470           0 :                 memset(&hints, '\0', sizeof(hints));
   14471           0 :                 hints.ai_flags = AI_NUMERICHOST;
   14472           0 :                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
   14473             :                                 NULL,
   14474             :                                 &hints,
   14475             :                                 &res);
   14476           0 :                 if (ret) {
   14477           0 :                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
   14478             :                                 remove_duplicate_addrs2_test_strings_vector[i]);
   14479           0 :                         return false;
   14480             :                 }
   14481           0 :                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
   14482           0 :                 memcpy(&test_vector[i].u.ss,
   14483           0 :                         res->ai_addr,
   14484           0 :                         res->ai_addrlen);
   14485           0 :                 freeaddrinfo(res);
   14486             :         }
   14487             : 
   14488           0 :         count = remove_duplicate_addrs2(test_vector, i);
   14489             : 
   14490           0 :         if (count != 14) {
   14491           0 :                 fprintf(stderr, "count wrong (%zu) should be 14\n",
   14492             :                         count);
   14493           0 :                 return false;
   14494             :         }
   14495             : 
   14496           0 :         for (i = 0; i < count; i++) {
   14497             :                 char addr[INET6_ADDRSTRLEN];
   14498             : 
   14499           0 :                 print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
   14500             : 
   14501           0 :                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
   14502           0 :                         fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
   14503             :                                 i,
   14504             :                                 addr,
   14505             :                                 remove_duplicate_addrs2_test_strings_result[i]);
   14506           0 :                         return false;
   14507             :                 }
   14508             :         }
   14509             : 
   14510           0 :         printf("run_local_remove_duplicate_addrs2: success\n");
   14511           0 :         return true;
   14512             : }
   14513             : 
   14514           0 : static bool run_local_tdb_opener(int dummy)
   14515             : {
   14516             :         TDB_CONTEXT *t;
   14517           0 :         unsigned v = 0;
   14518             : 
   14519             :         while (1) {
   14520           0 :                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
   14521             :                              O_RDWR|O_CREAT, 0755);
   14522           0 :                 if (t == NULL) {
   14523           0 :                         perror("tdb_open failed");
   14524           0 :                         return false;
   14525             :                 }
   14526           0 :                 tdb_close(t);
   14527             : 
   14528           0 :                 v += 1;
   14529           0 :                 printf("\r%u", v);
   14530             :         }
   14531             :         return true;
   14532             : }
   14533             : 
   14534           0 : static bool run_local_tdb_writer(int dummy)
   14535             : {
   14536             :         TDB_CONTEXT *t;
   14537           0 :         unsigned v = 0;
   14538             :         TDB_DATA val;
   14539             : 
   14540           0 :         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
   14541           0 :         if (t == 0) {
   14542           0 :                 perror("tdb_open failed");
   14543           0 :                 return 1;
   14544             :         }
   14545             : 
   14546           0 :         val.dptr = (uint8_t *)&v;
   14547           0 :         val.dsize = sizeof(v);
   14548             : 
   14549           0 :         while (1) {
   14550             :                 TDB_DATA data;
   14551             :                 int ret;
   14552             : 
   14553           0 :                 ret = tdb_store(t, val, val, 0);
   14554           0 :                 if (ret != 0) {
   14555           0 :                         printf("%s\n", tdb_errorstr(t));
   14556             :                 }
   14557           0 :                 v += 1;
   14558           0 :                 printf("\r%u", v);
   14559             : 
   14560           0 :                 data = tdb_fetch(t, val);
   14561           0 :                 if (data.dptr != NULL) {
   14562           0 :                         SAFE_FREE(data.dptr);
   14563             :                 }
   14564             :         }
   14565             :         return true;
   14566             : }
   14567             : 
   14568           0 : static bool run_local_canonicalize_path(int dummy)
   14569             : {
   14570           0 :         const char *src[] = {
   14571             :                         "/foo/..",
   14572             :                         "/..",
   14573             :                         "/foo/bar/../baz",
   14574             :                         "/foo/././",
   14575             :                         "/../foo",
   14576             :                         ".././././",
   14577             :                         ".././././../../../boo",
   14578             :                         "./..",
   14579             :                         "/",
   14580             :                         "/../../",
   14581             :                         "/foo/../",
   14582             :                         "/./././",
   14583             :                         "/./././.",
   14584             :                         "/.../././.",
   14585             :                         "/./././.foo",
   14586             :                         "/./././.foo.",
   14587             :                         "/./././foo.",
   14588             :                         "/foo/bar/..",
   14589             :                         "/foo/bar/../baz/",
   14590             :                         "////////////////",
   14591             :                         "/////////./././././.",
   14592             :                         "/./.././../.boo/../baz",
   14593             :                         "/a/component/path",
   14594             :                         "/a/component/path/",
   14595             :                         "/a/component/path/..",
   14596             :                         "/a/component/../path/",
   14597             :                         "///a/./././///component/../////path/",
   14598             :                         NULL
   14599             :                         };
   14600           0 :         const char *dst[] = {
   14601             :                         "/",
   14602             :                         "/",
   14603             :                         "/foo/baz",
   14604             :                         "/foo",
   14605             :                         "/foo",
   14606             :                         "/",
   14607             :                         "/boo",
   14608             :                         "/",
   14609             :                         "/",
   14610             :                         "/",
   14611             :                         "/",
   14612             :                         "/",
   14613             :                         "/",
   14614             :                         "/...",
   14615             :                         "/.foo",
   14616             :                         "/.foo.",
   14617             :                         "/foo.",
   14618             :                         "/foo",
   14619             :                         "/foo/baz",
   14620             :                         "/",
   14621             :                         "/",
   14622             :                         "/baz",
   14623             :                         "/a/component/path",
   14624             :                         "/a/component/path",
   14625             :                         "/a/component",
   14626             :                         "/a/path",
   14627             :                         "/a/path",
   14628             :                         NULL
   14629             :                         };
   14630             :         unsigned int i;
   14631             : 
   14632           0 :         for (i = 0; src[i] != NULL; i++) {
   14633           0 :                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
   14634           0 :                 if (d == NULL) {
   14635           0 :                         perror("talloc fail\n");
   14636           0 :                         return false;
   14637             :                 }
   14638           0 :                 if (strcmp(d, dst[i]) != 0) {
   14639           0 :                         d_fprintf(stderr,
   14640             :                                 "canonicalize mismatch %s -> %s != %s",
   14641             :                                 src[i], d, dst[i]);
   14642           0 :                         return false;
   14643             :                 }
   14644           0 :                 talloc_free(d);
   14645             :         }
   14646           0 :         return true;
   14647             : }
   14648             : struct session_setup_nt1_truncated_state {
   14649             :         uint16_t vwv[13];
   14650             :         uint8_t bytes[20];
   14651             : };
   14652             : 
   14653             : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
   14654             : 
   14655           0 : static struct tevent_req *smb1_session_setup_nt1_truncated_send(
   14656             :                 TALLOC_CTX *mem_ctx,
   14657             :                 struct tevent_context *ev,
   14658             :                 struct smbXcli_conn *conn)
   14659             : {
   14660           0 :         uint16_t *vwv = NULL;
   14661           0 :         uint8_t *bytes = NULL;
   14662           0 :         const char *pass = "12345678";
   14663           0 :         const char *uname = "z";
   14664           0 :         struct session_setup_nt1_truncated_state *state = NULL;
   14665           0 :         struct tevent_req *req = NULL;
   14666           0 :         struct tevent_req *subreq = NULL;
   14667             : 
   14668           0 :         req = tevent_req_create(mem_ctx,
   14669             :                                 &state,
   14670             :                                 struct session_setup_nt1_truncated_state);
   14671           0 :         if (req == NULL) {
   14672           0 :                 return NULL;
   14673             :         }
   14674           0 :         vwv = &state->vwv[0];
   14675           0 :         bytes = &state->bytes[0];
   14676             : 
   14677           0 :         SCVAL(vwv+0,  0, 0xff);
   14678           0 :         SCVAL(vwv+0,  1, 0);
   14679           0 :         SSVAL(vwv+1,  0, 0);
   14680           0 :         SSVAL(vwv+2,  0, 8192);
   14681           0 :         SSVAL(vwv+3,  0, 2);
   14682           0 :         SSVAL(vwv+4,  0, 1);
   14683           0 :         SIVAL(vwv+5,  0, 0);
   14684           0 :         SSVAL(vwv+7,  0, strlen(pass)); /* OEMPasswordLen */
   14685           0 :         SSVAL(vwv+8,  0, 0); /* UnicodePasswordLen */
   14686           0 :         SSVAL(vwv+9,  0, 0); /* reserved */
   14687           0 :         SSVAL(vwv+10, 0, 0); /* reserved */
   14688           0 :         SIVAL(vwv+11, 0, CAP_STATUS32);
   14689             : 
   14690           0 :         memcpy(bytes, pass, strlen(pass));
   14691           0 :         bytes += strlen(pass);
   14692           0 :         memcpy(bytes, uname, strlen(uname)+1);
   14693             : 
   14694           0 :         subreq = smb1cli_req_send(state, ev, conn,
   14695             :                                   SMBsesssetupX,
   14696             :                                   0, /*  additional_flags */
   14697             :                                   0, /*  clear_flags */
   14698             :                                   0, /*  additional_flags2 */
   14699             :                                   0, /*  clear_flags2 */
   14700             :                                   10000, /* timeout_msec */
   14701           0 :                                   getpid(),
   14702             :                                   NULL, /* tcon */
   14703             :                                   NULL, /* session */
   14704             :                                   13, /* wct */
   14705           0 :                                   state->vwv,
   14706           0 :                                   strlen(pass), /* Truncate length at password. */
   14707           0 :                                   state->bytes);
   14708           0 :         if (tevent_req_nomem(subreq, req)) {
   14709           0 :                 return tevent_req_post(req, ev);
   14710             :         }
   14711           0 :         tevent_req_set_callback(subreq,
   14712             :                                 smb1_session_setup_nt1_truncated_done,
   14713             :                                 req);
   14714           0 :         return req;
   14715             : }
   14716             : 
   14717           0 : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
   14718             : {
   14719           0 :         struct tevent_req *req =
   14720           0 :                 tevent_req_callback_data(subreq,
   14721             :                 struct tevent_req);
   14722           0 :         struct session_setup_nt1_truncated_state *state =
   14723           0 :                 tevent_req_data(req,
   14724             :                 struct session_setup_nt1_truncated_state);
   14725             :         NTSTATUS status;
   14726           0 :         struct smb1cli_req_expected_response expected[] = {
   14727             :         {
   14728             :                 .status = NT_STATUS_OK,
   14729             :                 .wct    = 3,
   14730             :         },
   14731             :         };
   14732             : 
   14733           0 :         status = smb1cli_req_recv(subreq, state,
   14734             :                                   NULL,
   14735             :                                   NULL,
   14736             :                                   NULL,
   14737             :                                   NULL,
   14738             :                                   NULL, /* pvwv_offset */
   14739             :                                   NULL,
   14740             :                                   NULL,
   14741             :                                   NULL, /* pbytes_offset */
   14742             :                                   NULL,
   14743             :                                   expected, ARRAY_SIZE(expected));
   14744           0 :         TALLOC_FREE(subreq);
   14745           0 :         if (tevent_req_nterror(req, status)) {
   14746           0 :                 return;
   14747             :         }
   14748           0 :         tevent_req_done(req);
   14749             : }
   14750             : 
   14751           0 : static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
   14752             : {
   14753           0 :         return tevent_req_simple_recv_ntstatus(req);
   14754             : }
   14755             : 
   14756           0 : static bool run_smb1_truncated_sesssetup(int dummy)
   14757             : {
   14758             :         struct tevent_context *ev;
   14759             :         struct tevent_req *req;
   14760             :         struct smbXcli_conn *conn;
   14761             :         struct sockaddr_storage ss;
   14762             :         NTSTATUS status;
   14763             :         int fd;
   14764             :         bool ok;
   14765             : 
   14766           0 :         printf("Starting send truncated SMB1 sesssetup.\n");
   14767             : 
   14768           0 :         ok = resolve_name(host, &ss, 0x20, true);
   14769           0 :         if (!ok) {
   14770           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14771           0 :                 return false;
   14772             :         }
   14773             : 
   14774           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14775           0 :         if (!NT_STATUS_IS_OK(status)) {
   14776           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14777             :                           nt_errstr(status));
   14778           0 :                 return false;
   14779             :         }
   14780             : 
   14781           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14782             :                                    NULL, 0, NULL);
   14783           0 :         if (conn == NULL) {
   14784           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14785           0 :                 return false;
   14786             :         }
   14787             : 
   14788           0 :         status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
   14789           0 :         if (!NT_STATUS_IS_OK(status)) {
   14790           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   14791           0 :                 return false;
   14792             :         }
   14793             : 
   14794           0 :         ev = samba_tevent_context_init(talloc_tos());
   14795           0 :         if (ev == NULL) {
   14796           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14797           0 :                 return false;
   14798             :         }
   14799             : 
   14800           0 :         req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
   14801           0 :         if (req == NULL) {
   14802           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
   14803           0 :                 return false;
   14804             :         }
   14805             : 
   14806           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   14807           0 :         if (!ok) {
   14808           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   14809             :                         nt_errstr(status));
   14810           0 :                 return false;
   14811             :         }
   14812             : 
   14813           0 :         status = smb1_session_setup_nt1_truncated_recv(req);
   14814           0 :         if (!NT_STATUS_IS_OK(status)) {
   14815           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
   14816             :                           "%s, expected NT_STATUS_OK\n",
   14817             :                           nt_errstr(status));
   14818           0 :                 return false;
   14819             :         }
   14820             : 
   14821           0 :         TALLOC_FREE(conn);
   14822           0 :         return true;
   14823             : }
   14824             : 
   14825             : struct smb1_negotiate_exit_state {
   14826             :         int dummy;
   14827             : };
   14828             : 
   14829             : static void smb1_negotiate_exit_done(struct tevent_req *subreq);
   14830             : 
   14831           0 : static struct tevent_req *smb1_negotiate_exit_send(
   14832             :                 TALLOC_CTX *mem_ctx,
   14833             :                 struct tevent_context *ev,
   14834             :                 struct smbXcli_conn *conn)
   14835             : {
   14836           0 :         struct smb1_negotiate_exit_state *state = NULL;
   14837           0 :         struct tevent_req *req = NULL;
   14838           0 :         struct tevent_req *subreq = NULL;
   14839             : 
   14840           0 :         req = tevent_req_create(mem_ctx,
   14841             :                                 &state,
   14842             :                                 struct smb1_negotiate_exit_state);
   14843           0 :         if (req == NULL) {
   14844           0 :                 return NULL;
   14845             :         }
   14846           0 :         subreq = smb1cli_req_send(state, ev, conn,
   14847             :                                   SMBexit,
   14848             :                                   0, /*  additional_flags */
   14849             :                                   0, /*  clear_flags */
   14850             :                                   0, /*  additional_flags2 */
   14851             :                                   0, /*  clear_flags2 */
   14852             :                                   10000, /* timeout_msec */
   14853           0 :                                   getpid(),
   14854             :                                   NULL, /* tcon */
   14855             :                                   NULL, /* session */
   14856             :                                   0, /* wct */
   14857             :                                   NULL,
   14858             :                                   0,
   14859             :                                   NULL);
   14860           0 :         if (tevent_req_nomem(subreq, req)) {
   14861           0 :                 return tevent_req_post(req, ev);
   14862             :         }
   14863           0 :         tevent_req_set_callback(subreq,
   14864             :                                 smb1_negotiate_exit_done,
   14865             :                                 req);
   14866           0 :         return req;
   14867             : }
   14868             : 
   14869           0 : static void smb1_negotiate_exit_done(struct tevent_req *subreq)
   14870             : {
   14871           0 :         struct tevent_req *req =
   14872           0 :                 tevent_req_callback_data(subreq,
   14873             :                 struct tevent_req);
   14874           0 :         struct smb1_negotiate_exit_state *state =
   14875           0 :                 tevent_req_data(req,
   14876             :                 struct smb1_negotiate_exit_state);
   14877             :         NTSTATUS status;
   14878           0 :         struct smb1cli_req_expected_response expected[] = {
   14879             :         {
   14880             :                 .status = NT_STATUS_OK,
   14881             :                 .wct    = 0,
   14882             :         },
   14883             :         };
   14884             : 
   14885           0 :         status = smb1cli_req_recv(subreq, state,
   14886             :                                   NULL,
   14887             :                                   NULL,
   14888             :                                   NULL,
   14889             :                                   NULL,
   14890             :                                   NULL, /* pvwv_offset */
   14891             :                                   NULL,
   14892             :                                   NULL,
   14893             :                                   NULL, /* pbytes_offset */
   14894             :                                   NULL,
   14895             :                                   expected, ARRAY_SIZE(expected));
   14896           0 :         TALLOC_FREE(subreq);
   14897           0 :         if (tevent_req_nterror(req, status)) {
   14898           0 :                 return;
   14899             :         }
   14900           0 :         tevent_req_done(req);
   14901             : }
   14902             : 
   14903           0 : static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
   14904             : {
   14905           0 :         return tevent_req_simple_recv_ntstatus(req);
   14906             : }
   14907             : 
   14908           0 : static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
   14909             :                          struct tevent_context *ev,
   14910             :                          struct smbXcli_conn *conn)
   14911             : {
   14912             :         struct tevent_req *req;
   14913             :         bool ok;
   14914             :         NTSTATUS status;
   14915           0 :         NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
   14916             : 
   14917           0 :         req = smb1_negotiate_exit_send(ev, ev, conn);
   14918           0 :         if (req == NULL) {
   14919           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
   14920           0 :                 return false;
   14921             :         }
   14922             : 
   14923           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   14924           0 :         if (!ok) {
   14925           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   14926             :                         nt_errstr(status));
   14927           0 :                 return false;
   14928             :         }
   14929             : 
   14930           0 :         status = smb1_negotiate_exit_recv(req);
   14931           0 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   14932           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
   14933             :                           "%s, expected ERRSRV, ERRinvnid\n",
   14934             :                           nt_errstr(status));
   14935           0 :                 return false;
   14936             :         }
   14937           0 :         return true;
   14938             : }
   14939             : 
   14940           0 : static bool run_smb1_negotiate_exit(int dummy)
   14941             : {
   14942             :         struct tevent_context *ev;
   14943             :         struct smbXcli_conn *conn;
   14944             :         struct sockaddr_storage ss;
   14945             :         NTSTATUS status;
   14946             :         int fd;
   14947             :         bool ok;
   14948             : 
   14949           0 :         printf("Starting send SMB1 negotiate+exit.\n");
   14950             : 
   14951           0 :         ok = resolve_name(host, &ss, 0x20, true);
   14952           0 :         if (!ok) {
   14953           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14954           0 :                 return false;
   14955             :         }
   14956             : 
   14957           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14958           0 :         if (!NT_STATUS_IS_OK(status)) {
   14959           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14960             :                           nt_errstr(status));
   14961           0 :                 return false;
   14962             :         }
   14963             : 
   14964           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14965             :                                    NULL, 0, NULL);
   14966           0 :         if (conn == NULL) {
   14967           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14968           0 :                 return false;
   14969             :         }
   14970             : 
   14971           0 :         status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
   14972           0 :         if (!NT_STATUS_IS_OK(status)) {
   14973           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   14974           0 :                 return false;
   14975             :         }
   14976             : 
   14977           0 :         ev = samba_tevent_context_init(talloc_tos());
   14978           0 :         if (ev == NULL) {
   14979           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14980           0 :                 return false;
   14981             :         }
   14982             : 
   14983             :         /*
   14984             :          * Call do_smb1_exit twice to catch a server crash, the
   14985             :          * server sends the first return code then crashes.
   14986             :          */
   14987           0 :         ok = do_smb1_exit(ev, ev, conn);
   14988           0 :         if (!ok) {
   14989           0 :                 d_fprintf(stderr, "do_smb1_exit (1) failed\n");
   14990           0 :                 return false;
   14991             :         }
   14992           0 :         ok = do_smb1_exit(ev, ev, conn);
   14993           0 :         if (!ok) {
   14994           0 :                 d_fprintf(stderr, "do_smb1_exit (2) failed\n");
   14995           0 :                 return false;
   14996             :         }
   14997             : 
   14998           0 :         TALLOC_FREE(conn);
   14999           0 :         return true;
   15000             : }
   15001             : 
   15002           0 : static bool run_smb1_negotiate_tcon(int dummy)
   15003             : {
   15004           0 :         struct cli_state *cli = NULL;
   15005           0 :         uint16_t cnum = 0;
   15006           0 :         uint16_t max_xmit = 0;
   15007             :         NTSTATUS status;
   15008             : 
   15009           0 :         printf("Starting send SMB1 negotiate+tcon.\n");
   15010           0 :         cli = open_nbt_connection();
   15011           0 :         if (cli == NULL) {
   15012           0 :                 d_fprintf(stderr, "open_nbt_connection failed!\n");
   15013           0 :                 return false;
   15014             :         }
   15015           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   15016             : 
   15017           0 :         status = smbXcli_negprot(cli->conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
   15018           0 :         if (!NT_STATUS_IS_OK(status)) {
   15019           0 :                 d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
   15020             :                         nt_errstr(status));
   15021           0 :                 return false;
   15022             :         }
   15023           0 :         status = cli_raw_tcon(cli,
   15024             :                               share,
   15025             :                               "",
   15026             :                               "?????",
   15027             :                               &max_xmit,
   15028             :                               &cnum);
   15029           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
   15030           0 :                 d_fprintf(stderr, "cli_raw_tcon failed - got %s "
   15031             :                         "(should get NT_STATUS_ACCESS_DENIED)!\n",
   15032             :                         nt_errstr(status));
   15033           0 :                 return false;
   15034             :         }
   15035           0 :         return true;
   15036             : }
   15037             : 
   15038           0 : static bool run_ign_bad_negprot(int dummy)
   15039             : {
   15040             :         struct tevent_context *ev;
   15041             :         struct tevent_req *req;
   15042             :         struct smbXcli_conn *conn;
   15043             :         struct sockaddr_storage ss;
   15044             :         NTSTATUS status;
   15045             :         int fd;
   15046             :         bool ok;
   15047             : 
   15048           0 :         printf("starting ignore bad negprot\n");
   15049             : 
   15050           0 :         ok = resolve_name(host, &ss, 0x20, true);
   15051           0 :         if (!ok) {
   15052           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15053           0 :                 return false;
   15054             :         }
   15055             : 
   15056           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15057           0 :         if (!NT_STATUS_IS_OK(status)) {
   15058           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15059             :                           nt_errstr(status));
   15060           0 :                 return false;
   15061             :         }
   15062             : 
   15063           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15064             :                                    NULL, 0, NULL);
   15065           0 :         if (conn == NULL) {
   15066           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15067           0 :                 return false;
   15068             :         }
   15069             : 
   15070           0 :         status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
   15071           0 :         if (NT_STATUS_IS_OK(status)) {
   15072           0 :                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
   15073           0 :                 return false;
   15074             :         }
   15075             : 
   15076           0 :         ev = samba_tevent_context_init(talloc_tos());
   15077           0 :         if (ev == NULL) {
   15078           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15079           0 :                 return false;
   15080             :         }
   15081             : 
   15082           0 :         req = smb1cli_session_setup_nt1_send(
   15083           0 :                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
   15084             :                 data_blob_null, data_blob_null, 0x40,
   15085             :                 "Windows 2000 2195", "Windows 2000 5.0");
   15086           0 :         if (req == NULL) {
   15087           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
   15088           0 :                 return false;
   15089             :         }
   15090             : 
   15091           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15092           0 :         if (!ok) {
   15093           0 :                 d_fprintf(stderr, "tevent_req_poll failed\n");
   15094           0 :                 return false;
   15095             :         }
   15096             : 
   15097           0 :         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
   15098             :                                                 NULL, NULL);
   15099           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
   15100           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
   15101             :                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
   15102             :                           nt_errstr(status));
   15103           0 :                 return false;
   15104             :         }
   15105             : 
   15106           0 :         TALLOC_FREE(conn);
   15107             : 
   15108           0 :         printf("starting ignore bad negprot\n");
   15109             : 
   15110           0 :         return true;
   15111             : }
   15112             : 
   15113             : 
   15114           2 : static double create_procs(bool (*fn)(int), bool *result)
   15115             : {
   15116             :         int i, status;
   15117             :         volatile pid_t *child_status;
   15118             :         volatile bool *child_status_out;
   15119             :         int synccount;
   15120           2 :         int tries = 8;
   15121             :         struct timeval start;
   15122             : 
   15123           2 :         synccount = 0;
   15124             : 
   15125           2 :         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
   15126           2 :         if (!child_status) {
   15127           0 :                 printf("Failed to setup shared memory\n");
   15128           0 :                 return -1;
   15129             :         }
   15130             : 
   15131           2 :         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
   15132           2 :         if (!child_status_out) {
   15133           0 :                 printf("Failed to setup result status shared memory\n");
   15134           0 :                 return -1;
   15135             :         }
   15136             : 
   15137           4 :         for (i = 0; i < torture_nprocs; i++) {
   15138           2 :                 child_status[i] = 0;
   15139           2 :                 child_status_out[i] = True;
   15140             :         }
   15141             : 
   15142           2 :         start = timeval_current();
   15143             : 
   15144           4 :         for (i=0;i<torture_nprocs;i++) {
   15145           2 :                 procnum = i;
   15146           2 :                 if (fork() == 0) {
   15147           0 :                         pid_t mypid = getpid();
   15148           0 :                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
   15149             : 
   15150           0 :                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
   15151             : 
   15152             :                         while (1) {
   15153           0 :                                 if (torture_open_connection(&current_cli, i)) break;
   15154           0 :                                 if (tries-- == 0) {
   15155           0 :                                         printf("pid %d failed to start\n", (int)getpid());
   15156           0 :                                         _exit(1);
   15157             :                                 }
   15158           0 :                                 smb_msleep(10); 
   15159             :                         }
   15160             : 
   15161           0 :                         child_status[i] = getpid();
   15162             : 
   15163           0 :                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
   15164             : 
   15165           0 :                         child_status_out[i] = fn(i);
   15166           0 :                         _exit(0);
   15167             :                 }
   15168             :         }
   15169             : 
   15170             :         do {
   15171           8 :                 synccount = 0;
   15172          16 :                 for (i=0;i<torture_nprocs;i++) {
   15173           8 :                         if (child_status[i]) synccount++;
   15174             :                 }
   15175           8 :                 if (synccount == torture_nprocs) break;
   15176           6 :                 smb_msleep(10);
   15177           6 :         } while (timeval_elapsed(&start) < 30);
   15178             : 
   15179           2 :         if (synccount != torture_nprocs) {
   15180           0 :                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
   15181           0 :                 *result = False;
   15182           0 :                 return timeval_elapsed(&start);
   15183             :         }
   15184             : 
   15185             :         /* start the client load */
   15186           2 :         start = timeval_current();
   15187             : 
   15188           4 :         for (i=0;i<torture_nprocs;i++) {
   15189           2 :                 child_status[i] = 0;
   15190             :         }
   15191             : 
   15192           2 :         printf("%d clients started\n", torture_nprocs);
   15193             : 
   15194           4 :         for (i=0;i<torture_nprocs;i++) {
   15195           2 :                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
   15196             :         }
   15197             : 
   15198           2 :         printf("\n");
   15199             : 
   15200           4 :         for (i=0;i<torture_nprocs;i++) {
   15201           2 :                 if (!child_status_out[i]) {
   15202           0 :                         *result = False;
   15203             :                 }
   15204             :         }
   15205           2 :         return timeval_elapsed(&start);
   15206             : }
   15207             : 
   15208             : #define FLAG_MULTIPROC 1
   15209             : 
   15210             : static struct {
   15211             :         const char *name;
   15212             :         bool (*fn)(int);
   15213             :         unsigned flags;
   15214             : } torture_ops[] = {
   15215             :         {
   15216             :                 .name = "FDPASS",
   15217             :                 .fn   = run_fdpasstest,
   15218             :         },
   15219             :         {
   15220             :                 .name = "LOCK1",
   15221             :                 .fn   = run_locktest1,
   15222             :         },
   15223             :         {
   15224             :                 .name = "LOCK2",
   15225             :                 .fn   =  run_locktest2,
   15226             :         },
   15227             :         {
   15228             :                 .name = "LOCK3",
   15229             :                 .fn   =  run_locktest3,
   15230             :         },
   15231             :         {
   15232             :                 .name = "LOCK4",
   15233             :                 .fn   =  run_locktest4,
   15234             :         },
   15235             :         {
   15236             :                 .name = "LOCK5",
   15237             :                 .fn   =  run_locktest5,
   15238             :         },
   15239             :         {
   15240             :                 .name = "LOCK6",
   15241             :                 .fn   =  run_locktest6,
   15242             :         },
   15243             :         {
   15244             :                 .name = "LOCK7",
   15245             :                 .fn   =  run_locktest7,
   15246             :         },
   15247             :         {
   15248             :                 .name = "LOCK8",
   15249             :                 .fn   =  run_locktest8,
   15250             :         },
   15251             :         {
   15252             :                 .name = "LOCK9A",
   15253             :                 .fn   =  run_locktest9a,
   15254             :         },
   15255             :         {
   15256             :                 .name = "LOCK9B",
   15257             :                 .fn   =  run_locktest9b,
   15258             :         },
   15259             :         {
   15260             :                 .name = "LOCK10",
   15261             :                 .fn   =  run_locktest10,
   15262             :         },
   15263             :         {
   15264             :                 .name = "LOCK11",
   15265             :                 .fn   =  run_locktest11,
   15266             :         },
   15267             :         {
   15268             :                 .name = "LOCK12",
   15269             :                 .fn   =  run_locktest12,
   15270             :         },
   15271             :         {
   15272             :                 .name = "LOCK13",
   15273             :                 .fn   =  run_locktest13,
   15274             :         },
   15275             :         {
   15276             :                 .name = "UNLINK",
   15277             :                 .fn   = run_unlinktest,
   15278             :         },
   15279             :         {
   15280             :                 .name = "BROWSE",
   15281             :                 .fn   = run_browsetest,
   15282             :         },
   15283             :         {
   15284             :                 .name = "ATTR",
   15285             :                 .fn   =   run_attrtest,
   15286             :         },
   15287             :         {
   15288             :                 .name = "TRANS2",
   15289             :                 .fn   = run_trans2test,
   15290             :         },
   15291             :         {
   15292             :                 .name  = "MAXFID",
   15293             :                 .fn    = run_maxfidtest,
   15294             :                 .flags = FLAG_MULTIPROC,
   15295             :         },
   15296             :         {
   15297             :                 .name  = "TORTURE",
   15298             :                 .fn    = run_torture,
   15299             :                 .flags = FLAG_MULTIPROC,
   15300             :         },
   15301             :         {
   15302             :                 .name  = "RANDOMIPC",
   15303             :                 .fn    = run_randomipc,
   15304             :         },
   15305             :         {
   15306             :                 .name  = "NEGNOWAIT",
   15307             :                 .fn    = run_negprot_nowait,
   15308             :         },
   15309             :         {
   15310             :                 .name  = "NBENCH",
   15311             :                 .fn    =  run_nbench,
   15312             :         },
   15313             :         {
   15314             :                 .name  = "NBENCH2",
   15315             :                 .fn    = run_nbench2,
   15316             :         },
   15317             :         {
   15318             :                 .name  = "OPLOCK1",
   15319             :                 .fn    =  run_oplock1,
   15320             :         },
   15321             :         {
   15322             :                 .name  = "OPLOCK2",
   15323             :                 .fn    =  run_oplock2,
   15324             :         },
   15325             :         {
   15326             :                 .name  = "OPLOCK4",
   15327             :                 .fn    =  run_oplock4,
   15328             :         },
   15329             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
   15330             :         {
   15331             :                 .name  = "OPLOCK5",
   15332             :                 .fn    =  run_oplock5,
   15333             :         },
   15334             : #endif
   15335             :         {
   15336             :                 .name  = "DIR",
   15337             :                 .fn    =  run_dirtest,
   15338             :         },
   15339             :         {
   15340             :                 .name  = "DIR1",
   15341             :                 .fn    =  run_dirtest1,
   15342             :         },
   15343             :         {
   15344             :                 .name  = "DIR-CREATETIME",
   15345             :                 .fn    =  run_dir_createtime,
   15346             :         },
   15347             :         {
   15348             :                 .name  = "DENY1",
   15349             :                 .fn    =  torture_denytest1,
   15350             :         },
   15351             :         {
   15352             :                 .name  = "DENY2",
   15353             :                 .fn    =  torture_denytest2,
   15354             :         },
   15355             :         {
   15356             :                 .name  = "TCON",
   15357             :                 .fn    =  run_tcon_test,
   15358             :         },
   15359             :         {
   15360             :                 .name  = "TCONDEV",
   15361             :                 .fn    =  run_tcon_devtype_test,
   15362             :         },
   15363             :         {
   15364             :                 .name  = "RW1",
   15365             :                 .fn    =  run_readwritetest,
   15366             :         },
   15367             :         {
   15368             :                 .name  = "RW2",
   15369             :                 .fn    =  run_readwritemulti,
   15370             :                 .flags = FLAG_MULTIPROC
   15371             :         },
   15372             :         {
   15373             :                 .name  = "RW3",
   15374             :                 .fn    =  run_readwritelarge,
   15375             :         },
   15376             :         {
   15377             :                 .name  = "RW-SIGNING",
   15378             :                 .fn    =  run_readwritelarge_signtest,
   15379             :         },
   15380             :         {
   15381             :                 .name  = "OPEN",
   15382             :                 .fn    = run_opentest,
   15383             :         },
   15384             :         {
   15385             :                 .name  = "POSIX",
   15386             :                 .fn    = run_simple_posix_open_test,
   15387             :         },
   15388             :         {
   15389             :                 .name  = "POSIX-APPEND",
   15390             :                 .fn    = run_posix_append,
   15391             :         },
   15392             :         {
   15393             :                 .name  = "POSIX-SYMLINK-ACL",
   15394             :                 .fn    = run_acl_symlink_test,
   15395             :         },
   15396             :         {
   15397             :                 .name  = "POSIX-SYMLINK-EA",
   15398             :                 .fn    = run_ea_symlink_test,
   15399             :         },
   15400             :         {
   15401             :                 .name  = "POSIX-STREAM-DELETE",
   15402             :                 .fn    = run_posix_stream_delete,
   15403             :         },
   15404             :         {
   15405             :                 .name  = "POSIX-OFD-LOCK",
   15406             :                 .fn    = run_posix_ofd_lock_test,
   15407             :         },
   15408             :         {
   15409             :                 .name  = "POSIX-BLOCKING-LOCK",
   15410             :                 .fn    = run_posix_blocking_lock,
   15411             :         },
   15412             :         {
   15413             :                 .name  = "POSIX-MKDIR",
   15414             :                 .fn    = run_posix_mkdir_test,
   15415             :         },
   15416             :         {
   15417             :                 .name  = "POSIX-ACL-OPLOCK",
   15418             :                 .fn    = run_posix_acl_oplock_test,
   15419             :         },
   15420             :         {
   15421             :                 .name  = "POSIX-ACL-SHAREROOT",
   15422             :                 .fn    = run_posix_acl_shareroot_test,
   15423             :         },
   15424             :         {
   15425             :                 .name  = "POSIX-LS-WILDCARD",
   15426             :                 .fn    = run_posix_ls_wildcard_test,
   15427             :         },
   15428             :         {
   15429             :                 .name  = "POSIX-LS-SINGLE",
   15430             :                 .fn    = run_posix_ls_single_test,
   15431             :         },
   15432             :         {
   15433             :                 .name  = "POSIX-READLINK",
   15434             :                 .fn    = run_posix_readlink_test,
   15435             :         },
   15436             :         {
   15437             :                 .name  = "POSIX-STAT",
   15438             :                 .fn    = run_posix_stat_test,
   15439             :         },
   15440             :         {
   15441             :                 .name  = "POSIX-SYMLINK-PARENT",
   15442             :                 .fn    = run_posix_symlink_parent_test,
   15443             :         },
   15444             :         {
   15445             :                 .name  = "POSIX-SYMLINK-CHMOD",
   15446             :                 .fn    = run_posix_symlink_chmod_test,
   15447             :         },
   15448             :         {
   15449             :                 .name  = "POSIX-SYMLINK-RENAME",
   15450             :                 .fn    = run_posix_symlink_rename_test,
   15451             :         },
   15452             :         {
   15453             :                 .name  = "POSIX-DIR-DEFAULT-ACL",
   15454             :                 .fn    = run_posix_dir_default_acl_test,
   15455             :         },
   15456             :         {
   15457             :                 .name  = "POSIX-SYMLINK-GETPATHINFO",
   15458             :                 .fn    = run_posix_symlink_getpathinfo_test,
   15459             :         },
   15460             :         {
   15461             :                 .name  = "POSIX-SYMLINK-SETPATHINFO",
   15462             :                 .fn    = run_posix_symlink_setpathinfo_test,
   15463             :         },
   15464             :         {
   15465             :                 .name  = "WINDOWS-BAD-SYMLINK",
   15466             :                 .fn    = run_symlink_open_test,
   15467             :         },
   15468             :         {
   15469             :                 .name  = "SMB1-WILD-MANGLE-UNLINK",
   15470             :                 .fn    = run_smb1_wild_mangle_unlink_test,
   15471             :         },
   15472             :         {
   15473             :                 .name  = "SMB1-WILD-MANGLE-RENAME",
   15474             :                 .fn    = run_smb1_wild_mangle_rename_test,
   15475             :         },
   15476             :         {
   15477             :                 .name  = "CASE-INSENSITIVE-CREATE",
   15478             :                 .fn    = run_case_insensitive_create,
   15479             :         },
   15480             :         {
   15481             :                 .name  = "ASYNC-ECHO",
   15482             :                 .fn    = run_async_echo,
   15483             :         },
   15484             :         {
   15485             :                 .name  = "UID-REGRESSION-TEST",
   15486             :                 .fn    = run_uid_regression_test,
   15487             :         },
   15488             :         {
   15489             :                 .name  = "SHORTNAME-TEST",
   15490             :                 .fn    = run_shortname_test,
   15491             :         },
   15492             :         {
   15493             :                 .name  = "ADDRCHANGE",
   15494             :                 .fn    = run_addrchange,
   15495             :         },
   15496             : #if 1
   15497             :         {
   15498             :                 .name  = "OPENATTR",
   15499             :                 .fn    = run_openattrtest,
   15500             :         },
   15501             : #endif
   15502             :         {
   15503             :                 .name  = "XCOPY",
   15504             :                 .fn    = run_xcopy,
   15505             :         },
   15506             :         {
   15507             :                 .name  = "RENAME",
   15508             :                 .fn    = run_rename,
   15509             :         },
   15510             :         {
   15511             :                 .name  = "RENAME-ACCESS",
   15512             :                 .fn    = run_rename_access,
   15513             :         },
   15514             :         {
   15515             :                 .name  = "OWNER-RIGHTS",
   15516             :                 .fn    = run_owner_rights,
   15517             :         },
   15518             :         {
   15519             :                 .name  = "DELETE",
   15520             :                 .fn    = run_deletetest,
   15521             :         },
   15522             :         {
   15523             :                 .name  = "DELETE-STREAM",
   15524             :                 .fn    = run_delete_stream,
   15525             :         },
   15526             :         {
   15527             :                 .name  = "DELETE-PRINT",
   15528             :                 .fn    = run_delete_print_test,
   15529             :         },
   15530             :         {
   15531             :                 .name  = "DELETE-LN",
   15532             :                 .fn    = run_deletetest_ln,
   15533             :         },
   15534             :         {
   15535             :                 .name  = "PROPERTIES",
   15536             :                 .fn    = run_properties,
   15537             :         },
   15538             :         {
   15539             :                 .name  = "MANGLE",
   15540             :                 .fn    = torture_mangle,
   15541             :         },
   15542             :         {
   15543             :                 .name  = "MANGLE1",
   15544             :                 .fn    = run_mangle1,
   15545             :         },
   15546             :         {
   15547             :                 .name  = "MANGLE-ILLEGAL",
   15548             :                 .fn    = run_mangle_illegal,
   15549             :         },
   15550             :         {
   15551             :                 .name  = "W2K",
   15552             :                 .fn    = run_w2ktest,
   15553             :         },
   15554             :         {
   15555             :                 .name  = "TRANS2SCAN",
   15556             :                 .fn    = torture_trans2_scan,
   15557             :         },
   15558             :         {
   15559             :                 .name  = "NTTRANSSCAN",
   15560             :                 .fn    = torture_nttrans_scan,
   15561             :         },
   15562             :         {
   15563             :                 .name  = "UTABLE",
   15564             :                 .fn    = torture_utable,
   15565             :         },
   15566             :         {
   15567             :                 .name  = "CASETABLE",
   15568             :                 .fn    = torture_casetable,
   15569             :         },
   15570             :         {
   15571             :                 .name  = "ERRMAPEXTRACT",
   15572             :                 .fn    = run_error_map_extract,
   15573             :         },
   15574             :         {
   15575             :                 .name  = "PIPE_NUMBER",
   15576             :                 .fn    = run_pipe_number,
   15577             :         },
   15578             :         {
   15579             :                 .name  = "TCON2",
   15580             :                 .fn    =  run_tcon2_test,
   15581             :         },
   15582             :         {
   15583             :                 .name  = "IOCTL",
   15584             :                 .fn    =  torture_ioctl_test,
   15585             :         },
   15586             :         {
   15587             :                 .name  = "CHKPATH",
   15588             :                 .fn    =  torture_chkpath_test,
   15589             :         },
   15590             :         {
   15591             :                 .name  = "FDSESS",
   15592             :                 .fn    = run_fdsesstest,
   15593             :         },
   15594             :         {
   15595             :                 .name  = "EATEST",
   15596             :                 .fn    = run_eatest,
   15597             :         },
   15598             :         {
   15599             :                 .name  = "SESSSETUP_BENCH",
   15600             :                 .fn    = run_sesssetup_bench,
   15601             :         },
   15602             :         {
   15603             :                 .name  = "CHAIN1",
   15604             :                 .fn    = run_chain1,
   15605             :         },
   15606             :         {
   15607             :                 .name  = "CHAIN2",
   15608             :                 .fn    = run_chain2,
   15609             :         },
   15610             :         {
   15611             :                 .name  = "CHAIN3",
   15612             :                 .fn    = run_chain3,
   15613             :         },
   15614             :         {
   15615             :                 .name  = "WINDOWS-WRITE",
   15616             :                 .fn    = run_windows_write,
   15617             :         },
   15618             :         {
   15619             :                 .name  = "LARGE_READX",
   15620             :                 .fn    = run_large_readx,
   15621             :         },
   15622             :         {
   15623             :                 .name  = "MSDFS-ATTRIBUTE",
   15624             :                 .fn    = run_msdfs_attribute,
   15625             :         },
   15626             :         {
   15627             :                 .name  = "NTTRANS-CREATE",
   15628             :                 .fn    = run_nttrans_create,
   15629             :         },
   15630             :         {
   15631             :                 .name  = "NTTRANS-FSCTL",
   15632             :                 .fn    = run_nttrans_fsctl,
   15633             :         },
   15634             :         {
   15635             :                 .name  = "CLI_ECHO",
   15636             :                 .fn    = run_cli_echo,
   15637             :         },
   15638             :         {
   15639             :                 .name  = "CLI_SPLICE",
   15640             :                 .fn    = run_cli_splice,
   15641             :         },
   15642             :         {
   15643             :                 .name  = "TLDAP",
   15644             :                 .fn    = run_tldap,
   15645             :         },
   15646             :         {
   15647             :                 .name  = "STREAMERROR",
   15648             :                 .fn    = run_streamerror,
   15649             :         },
   15650             :         {
   15651             :                 .name  = "NOTIFY-BENCH",
   15652             :                 .fn    = run_notify_bench,
   15653             :         },
   15654             :         {
   15655             :                 .name  = "NOTIFY-BENCH2",
   15656             :                 .fn    = run_notify_bench2,
   15657             :         },
   15658             :         {
   15659             :                 .name  = "NOTIFY-BENCH3",
   15660             :                 .fn    = run_notify_bench3,
   15661             :         },
   15662             :         {
   15663             :                 .name  = "BAD-NBT-SESSION",
   15664             :                 .fn    = run_bad_nbt_session,
   15665             :         },
   15666             :         {
   15667             :                 .name  = "IGN-BAD-NEGPROT",
   15668             :                 .fn    = run_ign_bad_negprot,
   15669             :         },
   15670             :         {
   15671             :                 .name  = "SMB-ANY-CONNECT",
   15672             :                 .fn    = run_smb_any_connect,
   15673             :         },
   15674             :         {
   15675             :                 .name  = "NOTIFY-ONLINE",
   15676             :                 .fn    = run_notify_online,
   15677             :         },
   15678             :         {
   15679             :                 .name  = "SMB2-BASIC",
   15680             :                 .fn    = run_smb2_basic,
   15681             :         },
   15682             :         {
   15683             :                 .name  = "SMB2-NEGPROT",
   15684             :                 .fn    = run_smb2_negprot,
   15685             :         },
   15686             :         {
   15687             :                 .name  = "SMB2-ANONYMOUS",
   15688             :                 .fn    = run_smb2_anonymous,
   15689             :         },
   15690             :         {
   15691             :                 .name  = "SMB2-SESSION-RECONNECT",
   15692             :                 .fn    = run_smb2_session_reconnect,
   15693             :         },
   15694             :         {
   15695             :                 .name  = "SMB2-TCON-DEPENDENCE",
   15696             :                 .fn    = run_smb2_tcon_dependence,
   15697             :         },
   15698             :         {
   15699             :                 .name  = "SMB2-MULTI-CHANNEL",
   15700             :                 .fn    = run_smb2_multi_channel,
   15701             :         },
   15702             :         {
   15703             :                 .name  = "SMB2-SESSION-REAUTH",
   15704             :                 .fn    = run_smb2_session_reauth,
   15705             :         },
   15706             :         {
   15707             :                 .name  = "SMB2-FTRUNCATE",
   15708             :                 .fn    = run_smb2_ftruncate,
   15709             :         },
   15710             :         {
   15711             :                 .name  = "SMB2-DIR-FSYNC",
   15712             :                 .fn    = run_smb2_dir_fsync,
   15713             :         },
   15714             :         {
   15715             :                 .name  = "SMB2-PATH-SLASH",
   15716             :                 .fn    = run_smb2_path_slash,
   15717             :         },
   15718             :         {
   15719             :                 .name  = "SMB1-SYSTEM-SECURITY",
   15720             :                 .fn    = run_smb1_system_security,
   15721             :         },
   15722             :         {
   15723             :                 .name  = "SMB2-SACL",
   15724             :                 .fn    = run_smb2_sacl,
   15725             :         },
   15726             :         {
   15727             :                 .name  = "SMB2-QUOTA1",
   15728             :                 .fn    = run_smb2_quota1,
   15729             :         },
   15730             :         {
   15731             :                 .name  = "SMB2-STREAM-ACL",
   15732             :                 .fn    = run_smb2_stream_acl,
   15733             :         },
   15734             :         {
   15735             :                 .name  = "SMB2-LIST-DIR-ASYNC",
   15736             :                 .fn    = run_list_dir_async_test,
   15737             :         },
   15738             :         {
   15739             :                 .name  = "SMB2-DEL-ON-CLOSE-NONEMPTY",
   15740             :                 .fn    = run_delete_on_close_non_empty,
   15741             :         },
   15742             :         {
   15743             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
   15744             :                 .fn    = run_delete_on_close_nonwrite_delete_yes_test,
   15745             :         },
   15746             :         {
   15747             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
   15748             :                 .fn    = run_delete_on_close_nonwrite_delete_no_test,
   15749             :         },
   15750             :         {
   15751             :                 .name  = "CLEANUP1",
   15752             :                 .fn    = run_cleanup1,
   15753             :         },
   15754             :         {
   15755             :                 .name  = "CLEANUP2",
   15756             :                 .fn    = run_cleanup2,
   15757             :         },
   15758             :         {
   15759             :                 .name  = "CLEANUP4",
   15760             :                 .fn    = run_cleanup4,
   15761             :         },
   15762             :         {
   15763             :                 .name  = "OPLOCK-CANCEL",
   15764             :                 .fn    = run_oplock_cancel,
   15765             :         },
   15766             :         {
   15767             :                 .name  = "SMB2-INVALID-PIPENAME",
   15768             :                 .fn    = run_smb2_invalid_pipename,
   15769             :         },
   15770             :         {
   15771             :                 .name  = "SMB1-TRUNCATED-SESSSETUP",
   15772             :                 .fn    = run_smb1_truncated_sesssetup,
   15773             :         },
   15774             :         {
   15775             :                 .name  = "SMB1-NEGOTIATE-EXIT",
   15776             :                 .fn    = run_smb1_negotiate_exit,
   15777             :         },
   15778             :         {
   15779             :                 .name  = "SMB1-NEGOTIATE-TCON",
   15780             :                 .fn    = run_smb1_negotiate_tcon,
   15781             :         },
   15782             :         {
   15783             :                 .name  = "PIDHIGH",
   15784             :                 .fn    = run_pidhigh,
   15785             :         },
   15786             :         {
   15787             :                 .name  = "LOCAL-SUBSTITUTE",
   15788             :                 .fn    = run_local_substitute,
   15789             :         },
   15790             :         {
   15791             :                 .name  = "LOCAL-GENCACHE",
   15792             :                 .fn    = run_local_gencache,
   15793             :         },
   15794             :         {
   15795             :                 .name  = "LOCAL-DBWRAP-WATCH1",
   15796             :                 .fn    = run_dbwrap_watch1,
   15797             :         },
   15798             :         {
   15799             :                 .name  = "LOCAL-DBWRAP-WATCH2",
   15800             :                 .fn    = run_dbwrap_watch2,
   15801             :         },
   15802             :         {
   15803             :                 .name  = "LOCAL-DBWRAP-WATCH3",
   15804             :                 .fn    = run_dbwrap_watch3,
   15805             :         },
   15806             :         {
   15807             :                 .name  = "LOCAL-DBWRAP-WATCH4",
   15808             :                 .fn    = run_dbwrap_watch4,
   15809             :         },
   15810             :         {
   15811             :                 .name  = "LOCAL-DBWRAP-DO-LOCKED1",
   15812             :                 .fn    = run_dbwrap_do_locked1,
   15813             :         },
   15814             :         {
   15815             :                 .name  = "LOCAL-MESSAGING-READ1",
   15816             :                 .fn    = run_messaging_read1,
   15817             :         },
   15818             :         {
   15819             :                 .name  = "LOCAL-MESSAGING-READ2",
   15820             :                 .fn    = run_messaging_read2,
   15821             :         },
   15822             :         {
   15823             :                 .name  = "LOCAL-MESSAGING-READ3",
   15824             :                 .fn    = run_messaging_read3,
   15825             :         },
   15826             :         {
   15827             :                 .name  = "LOCAL-MESSAGING-READ4",
   15828             :                 .fn    = run_messaging_read4,
   15829             :         },
   15830             :         {
   15831             :                 .name  = "LOCAL-MESSAGING-FDPASS1",
   15832             :                 .fn    = run_messaging_fdpass1,
   15833             :         },
   15834             :         {
   15835             :                 .name  = "LOCAL-MESSAGING-FDPASS2",
   15836             :                 .fn    = run_messaging_fdpass2,
   15837             :         },
   15838             :         {
   15839             :                 .name  = "LOCAL-MESSAGING-FDPASS2a",
   15840             :                 .fn    = run_messaging_fdpass2a,
   15841             :         },
   15842             :         {
   15843             :                 .name  = "LOCAL-MESSAGING-FDPASS2b",
   15844             :                 .fn    = run_messaging_fdpass2b,
   15845             :         },
   15846             :         {
   15847             :                 .name  = "LOCAL-MESSAGING-SEND-ALL",
   15848             :                 .fn    = run_messaging_send_all,
   15849             :         },
   15850             :         {
   15851             :                 .name  = "LOCAL-BASE64",
   15852             :                 .fn    = run_local_base64,
   15853             :         },
   15854             :         {
   15855             :                 .name  = "LOCAL-RBTREE",
   15856             :                 .fn    = run_local_rbtree,
   15857             :         },
   15858             :         {
   15859             :                 .name  = "LOCAL-MEMCACHE",
   15860             :                 .fn    = run_local_memcache,
   15861             :         },
   15862             :         {
   15863             :                 .name  = "LOCAL-STREAM-NAME",
   15864             :                 .fn    = run_local_stream_name,
   15865             :         },
   15866             :         {
   15867             :                 .name  = "LOCAL-STR-MATCH-MSWILD",
   15868             :                 .fn    = run_str_match_mswild,
   15869             :         },
   15870             :         {
   15871             :                 .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
   15872             :                 .fn    = run_str_match_regex_sub1,
   15873             :         },
   15874             :         {
   15875             :                 .name  = "WBCLIENT-MULTI-PING",
   15876             :                 .fn    = run_wbclient_multi_ping,
   15877             :         },
   15878             :         {
   15879             :                 .name  = "LOCAL-string_to_sid",
   15880             :                 .fn    = run_local_string_to_sid,
   15881             :         },
   15882             :         {
   15883             :                 .name  = "LOCAL-sid_to_string",
   15884             :                 .fn    = run_local_sid_to_string,
   15885             :         },
   15886             :         {
   15887             :                 .name  = "LOCAL-binary_to_sid",
   15888             :                 .fn    = run_local_binary_to_sid,
   15889             :         },
   15890             :         {
   15891             :                 .name  = "LOCAL-DBTRANS",
   15892             :                 .fn    = run_local_dbtrans,
   15893             :         },
   15894             :         {
   15895             :                 .name  = "LOCAL-TEVENT-POLL",
   15896             :                 .fn    = run_local_tevent_poll,
   15897             :         },
   15898             :         {
   15899             :                 .name  = "LOCAL-CONVERT-STRING",
   15900             :                 .fn    = run_local_convert_string,
   15901             :         },
   15902             :         {
   15903             :                 .name  = "LOCAL-CONV-AUTH-INFO",
   15904             :                 .fn    = run_local_conv_auth_info,
   15905             :         },
   15906             :         {
   15907             :                 .name  = "LOCAL-hex_encode_buf",
   15908             :                 .fn    = run_local_hex_encode_buf,
   15909             :         },
   15910             :         {
   15911             :                 .name  = "LOCAL-IDMAP-TDB-COMMON",
   15912             :                 .fn    = run_idmap_tdb_common_test,
   15913             :         },
   15914             :         {
   15915             :                 .name  = "LOCAL-remove_duplicate_addrs2",
   15916             :                 .fn    = run_local_remove_duplicate_addrs2,
   15917             :         },
   15918             :         {
   15919             :                 .name  = "local-tdb-opener",
   15920             :                 .fn    = run_local_tdb_opener,
   15921             :         },
   15922             :         {
   15923             :                 .name  = "local-tdb-writer",
   15924             :                 .fn    = run_local_tdb_writer,
   15925             :         },
   15926             :         {
   15927             :                 .name  = "LOCAL-DBWRAP-CTDB1",
   15928             :                 .fn    = run_local_dbwrap_ctdb1,
   15929             :         },
   15930             :         {
   15931             :                 .name  = "LOCAL-BENCH-PTHREADPOOL",
   15932             :                 .fn    = run_bench_pthreadpool,
   15933             :         },
   15934             :         {
   15935             :                 .name  = "LOCAL-PTHREADPOOL-TEVENT",
   15936             :                 .fn    = run_pthreadpool_tevent,
   15937             :         },
   15938             :         {
   15939             :                 .name  = "LOCAL-G-LOCK1",
   15940             :                 .fn    = run_g_lock1,
   15941             :         },
   15942             :         {
   15943             :                 .name  = "LOCAL-G-LOCK2",
   15944             :                 .fn    = run_g_lock2,
   15945             :         },
   15946             :         {
   15947             :                 .name  = "LOCAL-G-LOCK3",
   15948             :                 .fn    = run_g_lock3,
   15949             :         },
   15950             :         {
   15951             :                 .name  = "LOCAL-G-LOCK4",
   15952             :                 .fn    = run_g_lock4,
   15953             :         },
   15954             :         {
   15955             :                 .name  = "LOCAL-G-LOCK4A",
   15956             :                 .fn    = run_g_lock4a,
   15957             :         },
   15958             :         {
   15959             :                 .name  = "LOCAL-G-LOCK5",
   15960             :                 .fn    = run_g_lock5,
   15961             :         },
   15962             :         {
   15963             :                 .name  = "LOCAL-G-LOCK6",
   15964             :                 .fn    = run_g_lock6,
   15965             :         },
   15966             :         {
   15967             :                 .name  = "LOCAL-G-LOCK7",
   15968             :                 .fn    = run_g_lock7,
   15969             :         },
   15970             :         {
   15971             :                 .name  = "LOCAL-G-LOCK8",
   15972             :                 .fn    = run_g_lock8,
   15973             :         },
   15974             :         {
   15975             :                 .name  = "LOCAL-G-LOCK-PING-PONG",
   15976             :                 .fn    = run_g_lock_ping_pong,
   15977             :         },
   15978             :         {
   15979             :                 .name  = "LOCAL-CANONICALIZE-PATH",
   15980             :                 .fn    = run_local_canonicalize_path,
   15981             :         },
   15982             :         {
   15983             :                 .name  = "LOCAL-NAMEMAP-CACHE1",
   15984             :                 .fn    = run_local_namemap_cache1,
   15985             :         },
   15986             :         {
   15987             :                 .name  = "LOCAL-IDMAP-CACHE1",
   15988             :                 .fn    = run_local_idmap_cache1,
   15989             :         },
   15990             :         {
   15991             :                 .name  = "qpathinfo-bufsize",
   15992             :                 .fn    = run_qpathinfo_bufsize,
   15993             :         },
   15994             :         {
   15995             :                 .name  = "hide-new-files-timeout",
   15996             :                 .fn    = run_hidenewfiles,
   15997             :         },
   15998             : #ifdef CLUSTER_SUPPORT
   15999             :         {
   16000             :                 .name  = "ctdbd-conn1",
   16001             :                 .fn    = run_ctdbd_conn1,
   16002             :         },
   16003             : #endif
   16004             :         {
   16005             :                 .name  = "readdir-timestamp",
   16006             :                 .fn    = run_readdir_timestamp,
   16007             :         },
   16008             :         {
   16009             :                 .name  = "rpc-scale",
   16010             :                 .fn    = run_rpc_scale,
   16011             :         },
   16012             :         {
   16013             :                 .name = NULL,
   16014             :         },
   16015             : };
   16016             : 
   16017             : /****************************************************************************
   16018             : run a specified test or "ALL"
   16019             : ****************************************************************************/
   16020          56 : static bool run_test(const char *name)
   16021             : {
   16022          56 :         bool ret = True;
   16023          56 :         bool result = True;
   16024          56 :         bool found = False;
   16025             :         int i;
   16026             :         double t;
   16027          56 :         if (strequal(name,"ALL")) {
   16028           0 :                 for (i=0;torture_ops[i].name;i++) {
   16029           0 :                         run_test(torture_ops[i].name);
   16030             :                 }
   16031           0 :                 found = True;
   16032             :         }
   16033             : 
   16034       11032 :         for (i=0;torture_ops[i].name;i++) {
   16035       10976 :                 fstr_sprintf(randomfname, "\\XX%x", 
   16036       10976 :                          (unsigned)random());
   16037             : 
   16038       10976 :                 if (strequal(name, torture_ops[i].name)) {
   16039          56 :                         found = True;
   16040          56 :                         printf("Running %s\n", name);
   16041          56 :                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
   16042           2 :                                 t = create_procs(torture_ops[i].fn, &result);
   16043           2 :                                 if (!result) { 
   16044           0 :                                         ret = False;
   16045           0 :                                         printf("TEST %s FAILED!\n", name);
   16046             :                                 }
   16047             :                         } else {
   16048             :                                 struct timeval start;
   16049          54 :                                 start = timeval_current();
   16050          54 :                                 if (!torture_ops[i].fn(0)) {
   16051           6 :                                         ret = False;
   16052           6 :                                         printf("TEST %s FAILED!\n", name);
   16053             :                                 }
   16054          54 :                                 t = timeval_elapsed(&start);
   16055             :                         }
   16056          56 :                         printf("%s took %g secs\n\n", name, t);
   16057             :                 }
   16058             :         }
   16059             : 
   16060          56 :         if (!found) {
   16061           0 :                 printf("Did not find a test named %s\n", name);
   16062           0 :                 ret = False;
   16063             :         }
   16064             : 
   16065          56 :         return ret;
   16066             : }
   16067             : 
   16068             : 
   16069           0 : static void usage(void)
   16070             : {
   16071             :         int i;
   16072             : 
   16073           0 :         printf("WARNING samba4 test suite is much more complete nowadays.\n");
   16074           0 :         printf("Please use samba4 torture.\n\n");
   16075             : 
   16076           0 :         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
   16077             : 
   16078           0 :         printf("\t-d debuglevel\n");
   16079           0 :         printf("\t-U user%%pass\n");
   16080           0 :         printf("\t-k                    use kerberos\n");
   16081           0 :         printf("\t-N numprocs\n");
   16082           0 :         printf("\t-n my_netbios_name\n");
   16083           0 :         printf("\t-W workgroup\n");
   16084           0 :         printf("\t-o num_operations\n");
   16085           0 :         printf("\t-O socket_options\n");
   16086           0 :         printf("\t-m maximum protocol\n");
   16087           0 :         printf("\t-L use oplocks\n");
   16088           0 :         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
   16089           0 :         printf("\t-A showall\n");
   16090           0 :         printf("\t-p port\n");
   16091           0 :         printf("\t-s seed\n");
   16092           0 :         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
   16093           0 :         printf("\t-f filename           filename to test\n");
   16094           0 :         printf("\t-e                    encrypt\n");
   16095           0 :         printf("\n\n");
   16096             : 
   16097           0 :         printf("tests are:");
   16098           0 :         for (i=0;torture_ops[i].name;i++) {
   16099           0 :                 printf(" %s", torture_ops[i].name);
   16100             :         }
   16101           0 :         printf("\n");
   16102             : 
   16103           0 :         printf("default test is ALL\n");
   16104             : 
   16105           0 :         exit(1);
   16106             : }
   16107             : 
   16108             : /****************************************************************************
   16109             :   main program
   16110             : ****************************************************************************/
   16111          56 :  int main(int argc,char *argv[])
   16112             : {
   16113             :         int opt, i;
   16114             :         char *p;
   16115          56 :         int gotuser = 0;
   16116          56 :         int gotpass = 0;
   16117          56 :         bool correct = True;
   16118          56 :         TALLOC_CTX *frame = talloc_stackframe();
   16119          56 :         int seed = time(NULL);
   16120             : 
   16121             : #ifdef HAVE_SETBUFFER
   16122          56 :         setbuffer(stdout, NULL, 0);
   16123             : #endif
   16124             : 
   16125          56 :         setup_logging("smbtorture", DEBUG_STDOUT);
   16126             : 
   16127          56 :         smb_init_locale();
   16128          56 :         fault_setup();
   16129             : 
   16130          56 :         if (is_default_dyn_CONFIGFILE()) {
   16131          56 :                 if(getenv("SMB_CONF_PATH")) {
   16132          56 :                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
   16133             :                 }
   16134             :         }
   16135          56 :         lp_load_global(get_dyn_CONFIGFILE());
   16136          56 :         load_interfaces();
   16137             : 
   16138          56 :         if (argc < 2) {
   16139           0 :                 usage();
   16140             :         }
   16141             : 
   16142         996 :         for(p = argv[1]; *p; p++)
   16143         940 :           if(*p == '\\')
   16144           0 :             *p = '/';
   16145             : 
   16146          56 :         if (strncmp(argv[1], "//", 2)) {
   16147           0 :                 usage();
   16148             :         }
   16149             : 
   16150          56 :         fstrcpy(host, &argv[1][2]);
   16151          56 :         p = strchr_m(&host[2],'/');
   16152          56 :         if (!p) {
   16153           0 :                 usage();
   16154             :         }
   16155          56 :         *p = 0;
   16156          56 :         fstrcpy(share, p+1);
   16157             : 
   16158          56 :         fstrcpy(myname, get_myname(talloc_tos()));
   16159          56 :         if (!*myname) {
   16160           0 :                 fprintf(stderr, "Failed to get my hostname.\n");
   16161           0 :                 return 1;
   16162             :         }
   16163             : 
   16164          56 :         if (*username == 0 && getenv("LOGNAME")) {
   16165           0 :           fstrcpy(username,getenv("LOGNAME"));
   16166             :         }
   16167             : 
   16168          56 :         argc--;
   16169          56 :         argv++;
   16170             : 
   16171          56 :         fstrcpy(workgroup, lp_workgroup());
   16172             : 
   16173         218 :         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
   16174           4 :                != EOF) {
   16175         108 :                 switch (opt) {
   16176           0 :                 case 'p':
   16177           0 :                         port_to_use = atoi(optarg);
   16178           0 :                         break;
   16179           0 :                 case 's':
   16180           0 :                         seed = atoi(optarg);
   16181           0 :                         break;
   16182           0 :                 case 'W':
   16183           0 :                         fstrcpy(workgroup,optarg);
   16184           0 :                         break;
   16185           0 :                 case 'm':
   16186           0 :                         lp_set_cmdline("client max protocol", optarg);
   16187           0 :                         break;
   16188           0 :                 case 'N':
   16189           0 :                         torture_nprocs = atoi(optarg);
   16190           0 :                         break;
   16191           0 :                 case 'o':
   16192           0 :                         torture_numops = atoi(optarg);
   16193           0 :                         break;
   16194           0 :                 case 'd':
   16195           0 :                         lp_set_cmdline("log level", optarg);
   16196           0 :                         break;
   16197           0 :                 case 'O':
   16198           0 :                         sockops = optarg;
   16199           0 :                         break;
   16200           0 :                 case 'L':
   16201           0 :                         use_oplocks = True;
   16202           0 :                         break;
   16203          52 :                 case 'l':
   16204          52 :                         local_path = optarg;
   16205          52 :                         break;
   16206           0 :                 case 'A':
   16207           0 :                         torture_showall = True;
   16208           0 :                         break;
   16209           0 :                 case 'n':
   16210           0 :                         fstrcpy(myname, optarg);
   16211           0 :                         break;
   16212           0 :                 case 'c':
   16213           0 :                         client_txt = optarg;
   16214           0 :                         break;
   16215           0 :                 case 'e':
   16216           0 :                         do_encrypt = true;
   16217           0 :                         break;
   16218           0 :                 case 'k':
   16219             : #ifdef HAVE_KRB5
   16220           0 :                         use_kerberos = True;
   16221             : #else
   16222             :                         d_printf("No kerberos support compiled in\n");
   16223             :                         exit(1);
   16224             : #endif
   16225           0 :                         break;
   16226          56 :                 case 'U':
   16227          56 :                         gotuser = 1;
   16228          56 :                         fstrcpy(username,optarg);
   16229          56 :                         p = strchr_m(username,'%');
   16230          56 :                         if (p) {
   16231          56 :                                 *p = 0;
   16232          56 :                                 fstrcpy(password, p+1);
   16233          56 :                                 gotpass = 1;
   16234             :                         }
   16235          56 :                         break;
   16236           0 :                 case 'b':
   16237           0 :                         fstrcpy(multishare_conn_fname, optarg);
   16238           0 :                         use_multishare_conn = True;
   16239           0 :                         break;
   16240           0 :                 case 'B':
   16241           0 :                         torture_blocksize = atoi(optarg);
   16242           0 :                         break;
   16243           0 :                 case 'f':
   16244           0 :                         test_filename = SMB_STRDUP(optarg);
   16245           0 :                         break;
   16246           0 :                 default:
   16247           0 :                         printf("Unknown option %c (%d)\n", (char)opt, opt);
   16248           0 :                         usage();
   16249             :                 }
   16250             :         }
   16251             : 
   16252          56 :         d_printf("using seed %d\n", seed);
   16253             : 
   16254          56 :         srandom(seed);
   16255             : 
   16256          56 :         if(use_kerberos && !gotuser) gotpass = True;
   16257             : 
   16258         110 :         while (!gotpass) {
   16259           0 :                 char pwd[256] = {0};
   16260             :                 int rc;
   16261             : 
   16262           0 :                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
   16263           0 :                 if (rc == 0) {
   16264           0 :                         fstrcpy(password, pwd);
   16265           0 :                         gotpass = 1;
   16266             :                 }
   16267             :         }
   16268             : 
   16269          56 :         printf("host=%s share=%s user=%s myname=%s\n", 
   16270             :                host, share, username, myname);
   16271             : 
   16272          56 :         torture_creds = cli_session_creds_init(frame,
   16273             :                                                username,
   16274             :                                                workgroup,
   16275             :                                                NULL, /* realm */
   16276             :                                                password,
   16277             :                                                use_kerberos,
   16278             :                                                false, /* fallback_after_kerberos */
   16279             :                                                false, /* use_ccache */
   16280             :                                                false); /* password_is_nt_hash */
   16281          56 :         if (torture_creds == NULL) {
   16282           0 :                 d_printf("cli_session_creds_init() failed.\n");
   16283           0 :                 exit(1);
   16284             :         }
   16285             : 
   16286          56 :         if (argc == optind) {
   16287           0 :                 correct = run_test("ALL");
   16288             :         } else {
   16289         112 :                 for (i=optind;i<argc;i++) {
   16290          56 :                         if (!run_test(argv[i])) {
   16291           6 :                                 correct = False;
   16292             :                         }
   16293             :                 }
   16294             :         }
   16295             : 
   16296          56 :         TALLOC_FREE(frame);
   16297             : 
   16298          56 :         if (correct) {
   16299          50 :                 return(0);
   16300             :         } else {
   16301           6 :                 return(1);
   16302             :         }
   16303             : }

Generated by: LCOV version 1.13