LCOV - code coverage report
Current view: top level - source3/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 4429 8182 54.1 %
Date: 2024-04-13 12:30:31 Functions: 193 240 80.4 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Andrew Tridgell 1997-1998
       5             :    Copyright (C) Jeremy Allison 2009
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/shmem.h"
      23             : #include "libsmb/namequery.h"
      24             : #include "wbc_async.h"
      25             : #include "torture/proto.h"
      26             : #include "libcli/security/security.h"
      27             : #include "tldap.h"
      28             : #include "tldap_util.h"
      29             : #include "tldap_gensec_bind.h"
      30             : #include "../librpc/gen_ndr/svcctl.h"
      31             : #include "../lib/util/memcache.h"
      32             : #include "nsswitch/winbind_client.h"
      33             : #include "dbwrap/dbwrap.h"
      34             : #include "dbwrap/dbwrap_open.h"
      35             : #include "dbwrap/dbwrap_rbt.h"
      36             : #include "async_smb.h"
      37             : #include "libsmb/libsmb.h"
      38             : #include "libsmb/clirap.h"
      39             : #include "trans2.h"
      40             : #include "libsmb/nmblib.h"
      41             : #include "../lib/util/tevent_ntstatus.h"
      42             : #include "util_tdb.h"
      43             : #include "../libcli/smb/read_smb.h"
      44             : #include "../libcli/smb/smbXcli_base.h"
      45             : #include "lib/util/sys_rw_data.h"
      46             : #include "lib/util/base64.h"
      47             : #include "lib/util/time.h"
      48             : #include "lib/gencache.h"
      49             : #include "lib/util/sys_rw.h"
      50             : #include "lib/util/asn1.h"
      51             : #include "lib/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         200 : static bool force_cli_encryption(struct cli_state *c,
      94             :                         const char *sharename)
      95             : {
      96           0 :         uint16_t major, minor;
      97           0 :         uint32_t caplow, caphigh;
      98           0 :         NTSTATUS status;
      99             : 
     100         200 :         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         200 :         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
     108             :                                              &caphigh);
     109         200 :         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         200 :         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         200 :         status = cli_smb1_setup_encryption(c, torture_creds);
     124         200 :         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         200 :         return true;
     132             : }
     133             : 
     134             : 
     135         100 : static struct cli_state *open_nbt_connection(void)
     136             : {
     137           0 :         struct cli_state *c;
     138           0 :         NTSTATUS status;
     139         100 :         int flags = 0;
     140             : 
     141         100 :         if (disable_spnego) {
     142           0 :                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
     143             :         }
     144             : 
     145         100 :         if (use_oplocks) {
     146           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     147             :         }
     148             : 
     149         100 :         if (use_level_II_oplocks) {
     150           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     151             :         }
     152             : 
     153         100 :         if (force_dos_errors) {
     154           0 :                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
     155             :         }
     156             : 
     157         100 :         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
     158             :                                 signing_state, flags, &c);
     159         100 :         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         100 :         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
     165             : 
     166         100 :         return c;
     167             : }
     168             : 
     169             : /****************************************************************************
     170             :  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
     171             : ****************************************************************************/
     172             : 
     173           4 : static bool cli_bad_session_request(int fd,
     174             :                          struct nmb_name *calling, struct nmb_name *called)
     175             : {
     176           0 :         TALLOC_CTX *frame;
     177           0 :         uint8_t len_buf[4];
     178           0 :         struct iovec iov[3];
     179           0 :         ssize_t len;
     180           0 :         uint8_t *inbuf;
     181           0 :         int err;
     182           4 :         bool ret = false;
     183           0 :         uint8_t message_type;
     184           0 :         uint8_t error;
     185           0 :         struct tevent_context *ev;
     186           0 :         struct tevent_req *req;
     187             : 
     188           4 :         frame = talloc_stackframe();
     189             : 
     190           4 :         iov[0].iov_base = len_buf;
     191           4 :         iov[0].iov_len  = sizeof(len_buf);
     192             : 
     193             :         /* put in the destination name */
     194             : 
     195           4 :         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
     196           4 :                                       called->name_type);
     197           4 :         if (iov[1].iov_base == NULL) {
     198           0 :                 goto fail;
     199             :         }
     200           4 :         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
     201           4 :                                   talloc_get_size(iov[1].iov_base));
     202             : 
     203             :         /* and my name */
     204             : 
     205           4 :         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
     206           4 :                                       calling->name_type);
     207           4 :         if (iov[2].iov_base == NULL) {
     208           0 :                 goto fail;
     209             :         }
     210           4 :         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
     211           4 :                                   talloc_get_size(iov[2].iov_base));
     212             : 
     213             :         /* Deliberately corrupt the name len (first byte) */
     214           4 :         *((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           4 :         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
     226           4 :         SCVAL(len_buf,0,0x81);
     227             : 
     228           4 :         len = write_data_iov(fd, iov, 3);
     229           4 :         if (len == -1) {
     230           0 :                 goto fail;
     231             :         }
     232             : 
     233           4 :         ev = samba_tevent_context_init(frame);
     234           4 :         if (ev == NULL) {
     235           0 :                 goto fail;
     236             :         }
     237           4 :         req = read_smb_send(frame, ev, fd);
     238           4 :         if (req == NULL) {
     239           0 :                 goto fail;
     240             :         }
     241           4 :         if (!tevent_req_poll(req, ev)) {
     242           0 :                 goto fail;
     243             :         }
     244           4 :         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
     245           4 :         if (len == -1) {
     246           0 :                 errno = err;
     247           0 :                 goto fail;
     248             :         }
     249           4 :         TALLOC_FREE(ev);
     250             : 
     251           4 :         message_type = CVAL(inbuf, 0);
     252           4 :         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           4 :         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           4 :         error = CVAL(inbuf, 4);
     265           4 :         if (error !=  0x82) {
     266           0 :                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
     267             :                           (int)error);
     268           0 :                 goto fail;
     269             :         }
     270             : 
     271           4 :         ret = true;
     272           4 : fail:
     273           4 :         TALLOC_FREE(frame);
     274           4 :         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           0 :         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           0 :         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         497 : static bool torture_open_connection_share(struct cli_state **c,
     336             :                                    const char *hostname, 
     337             :                                    const char *sharename,
     338             :                                    int flags)
     339             : {
     340           0 :         NTSTATUS status;
     341             : 
     342         497 :         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         497 :         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         495 :         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
     358             : 
     359         495 :         if (do_encrypt) {
     360         198 :                 return force_cli_encryption(*c,
     361             :                                         sharename);
     362             :         }
     363         297 :         return True;
     364             : }
     365             : 
     366         497 : bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
     367             : {
     368         497 :         char **unc_list = NULL;
     369         497 :         int num_unc_names = 0;
     370           0 :         bool result;
     371             : 
     372         497 :         if (use_multishare_conn==True) {
     373           0 :                 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         497 :         return torture_open_connection_share(c, host, share, flags);
     396             : }
     397             : 
     398         485 : bool torture_open_connection(struct cli_state **c, int conn_index)
     399             : {
     400         485 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
     401             : 
     402         485 :         if (use_oplocks) {
     403           8 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     404             :         }
     405         485 :         if (use_level_II_oplocks) {
     406           8 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     407             :         }
     408             : 
     409         485 :         return torture_open_connection_flags(c, conn_index, flags);
     410             : }
     411             : 
     412          90 : bool torture_init_connection(struct cli_state **pcli)
     413             : {
     414           0 :         struct cli_state *cli;
     415             : 
     416          90 :         cli = open_nbt_connection();
     417          90 :         if (cli == NULL) {
     418           0 :                 return false;
     419             :         }
     420             : 
     421          90 :         *pcli = cli;
     422          90 :         return true;
     423             : }
     424             : 
     425           5 : bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
     426             : {
     427           5 :         uint16_t old_vuid = cli_state_get_uid(cli);
     428           0 :         NTSTATUS status;
     429           0 :         bool ret;
     430             : 
     431           5 :         cli_state_set_uid(cli, 0);
     432           5 :         status = cli_session_setup_creds(cli, torture_creds);
     433           5 :         ret = NT_STATUS_IS_OK(status);
     434           5 :         *new_vuid = cli_state_get_uid(cli);
     435           5 :         cli_state_set_uid(cli, old_vuid);
     436           5 :         return ret;
     437             : }
     438             : 
     439             : 
     440         421 : bool torture_close_connection(struct cli_state *c)
     441             : {
     442         421 :         bool ret = True;
     443           0 :         NTSTATUS status;
     444             : 
     445         421 :         status = cli_tdis(c);
     446         421 :         if (!NT_STATUS_IS_OK(status)) {
     447           5 :                 printf("tdis failed (%s)\n", nt_errstr(status));
     448           5 :                 ret = False;
     449             :         }
     450             : 
     451         421 :         cli_shutdown(c);
     452             : 
     453         421 :         return ret;
     454             : }
     455             : 
     456          48 : void torture_conn_set_sockopt(struct cli_state *cli)
     457             : {
     458          48 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     459          48 : }
     460             : 
     461          58 : static NTSTATUS torture_delete_fn(struct file_info *finfo,
     462             :                                   const char *pattern,
     463             :                                   void *state)
     464             : {
     465           0 :         NTSTATUS status;
     466          58 :         char *filename = NULL;
     467          58 :         char *dirname = NULL;
     468          58 :         char *p = NULL;
     469          58 :         TALLOC_CTX *frame = talloc_stackframe();
     470          58 :         struct cli_state *cli = (struct cli_state *)state;
     471             : 
     472          58 :         if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
     473          36 :                 TALLOC_FREE(frame);
     474          36 :                 return NT_STATUS_OK;
     475             :         }
     476             : 
     477          22 :         dirname = talloc_strdup(frame, pattern);
     478          22 :         if (dirname == NULL) {
     479           0 :                 TALLOC_FREE(frame);
     480           0 :                 return NT_STATUS_NO_MEMORY;
     481             :         }
     482          22 :         p = strrchr_m(dirname, '\\');
     483          22 :         if (p != NULL) {
     484             :                 /* Remove the terminating '\' */
     485          22 :                 *p = '\0';
     486             :         }
     487          22 :         if (dirname[0] != '\0') {
     488          22 :                 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          22 :         if (filename == NULL) {
     498           0 :                 TALLOC_FREE(frame);
     499           0 :                 return NT_STATUS_NO_MEMORY;
     500             :         }
     501          22 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     502           5 :                 char *subdirname = talloc_asprintf(frame,
     503             :                                                    "%s\\*",
     504             :                                                    filename);
     505           5 :                 if (subdirname == NULL) {
     506           0 :                         TALLOC_FREE(frame);
     507           0 :                         return NT_STATUS_NO_MEMORY;
     508             :                 }
     509           5 :                 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           5 :                 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           5 :                 status = cli_rmdir(cli, filename);
     525             :         } else {
     526          17 :                 status = cli_unlink(cli,
     527             :                                     filename,
     528             :                                     FILE_ATTRIBUTE_SYSTEM |
     529             :                                         FILE_ATTRIBUTE_HIDDEN);
     530             :         }
     531          22 :         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          22 :         TALLOC_FREE(frame);
     545          22 :         return status;
     546             : }
     547             : 
     548          30 : void torture_deltree(struct cli_state *cli, const char *dname)
     549             : {
     550          30 :         char *mask = NULL;
     551           0 :         NTSTATUS status;
     552             : 
     553             :         /* It might be a file */
     554          30 :         (void)cli_unlink(cli,
     555             :                          dname,
     556             :                          FILE_ATTRIBUTE_SYSTEM |
     557             :                                 FILE_ATTRIBUTE_HIDDEN);
     558             : 
     559          30 :         mask = talloc_asprintf(cli,
     560             :                                "%s\\*",
     561             :                                dname);
     562          30 :         if (mask == NULL) {
     563           0 :                 printf("torture_deltree: talloc_asprintf failed\n");
     564           0 :                 return;
     565             :         }
     566             : 
     567          30 :         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          30 :         if (!NT_STATUS_IS_OK(status)) {
     575          17 :                 printf("torture_deltree: cli_list of %s failed (%s)\n",
     576             :                         mask,
     577             :                         nt_errstr(status));
     578             :         }
     579          30 :         TALLOC_FREE(mask);
     580          30 :         status = cli_rmdir(cli, dname);
     581          30 :         if (!NT_STATUS_IS_OK(status)) {
     582          17 :                 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          53 : static bool check_both_error(int line, NTSTATUS status,
     590             :                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     591             : {
     592          53 :         if (NT_STATUS_IS_DOS(status)) {
     593           0 :                 uint8_t cclass;
     594           0 :                 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          53 :                 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          53 :         return true;
     619             : }
     620             : 
     621             : 
     622             : /* check if the server produced the expected error code */
     623          38 : static bool check_error(int line, NTSTATUS status,
     624             :                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     625             : {
     626          38 :         if (NT_STATUS_IS_DOS(status)) {
     627           0 :                 uint8_t cclass;
     628           0 :                 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          38 :                 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          37 :         return True;
     657             : }
     658             : 
     659           9 : NTSTATUS cli_qpathinfo1(struct cli_state *cli,
     660             :                         const char *fname,
     661             :                         time_t *change_time,
     662             :                         time_t *access_time,
     663             :                         time_t *write_time,
     664             :                         off_t *size,
     665             :                         uint32_t *pattr)
     666             : {
     667           9 :         int timezone = smb1cli_conn_server_time_zone(cli->conn);
     668           9 :         time_t (*date_fn)(const void *buf, int serverzone) = NULL;
     669           9 :         uint8_t *rdata = NULL;
     670           0 :         uint32_t num_rdata;
     671           0 :         NTSTATUS status;
     672             : 
     673           9 :         status = cli_qpathinfo(talloc_tos(),
     674             :                                cli,
     675             :                                fname,
     676             :                                SMB_INFO_STANDARD,
     677             :                                22,
     678             :                                CLI_BUFFER_SIZE,
     679             :                                &rdata,
     680             :                                &num_rdata);
     681           9 :         if (!NT_STATUS_IS_OK(status)) {
     682           4 :                 return status;
     683             :         }
     684           5 :         if (cli->win95) {
     685           0 :                 date_fn = make_unix_date;
     686             :         } else {
     687           5 :                 date_fn = make_unix_date2;
     688             :         }
     689             : 
     690           5 :         if (change_time) {
     691           5 :                 *change_time = date_fn(rdata + 0, timezone);
     692             :         }
     693           5 :         if (access_time) {
     694           5 :                 *access_time = date_fn(rdata + 4, timezone);
     695             :         }
     696           5 :         if (write_time) {
     697           5 :                 *write_time = date_fn(rdata + 8, timezone);
     698             :         }
     699           5 :         if (size) {
     700           5 :                 *size = PULL_LE_U32(rdata, 12);
     701             :         }
     702           5 :         if (pattr) {
     703           0 :                 *pattr = PULL_LE_U16(rdata, l1_attrFile);
     704             :         }
     705           5 :         return NT_STATUS_OK;
     706             : }
     707             : 
     708           0 : static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
     709             : {
     710           0 :         NTSTATUS status;
     711             : 
     712           0 :         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     713             : 
     714           0 :         while (!NT_STATUS_IS_OK(status)) {
     715           0 :                 if (!check_both_error(__LINE__, status, ERRDOS,
     716           0 :                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
     717           0 :                         return false;
     718             :                 }
     719             : 
     720           0 :                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     721             :         }
     722             : 
     723           0 :         return true;
     724             : }
     725             : 
     726             : 
     727           0 : static bool rw_torture(struct cli_state *c)
     728             : {
     729           0 :         const char *lockfname = "\\torture.lck";
     730           0 :         fstring fname;
     731           0 :         uint16_t fnum;
     732           0 :         uint16_t fnum2;
     733           0 :         pid_t pid2, pid = getpid();
     734           0 :         int i, j;
     735           0 :         char buf[1024];
     736           0 :         bool correct = True;
     737           0 :         size_t nread = 0;
     738           0 :         NTSTATUS status;
     739             : 
     740           0 :         memset(buf, '\0', sizeof(buf));
     741             : 
     742           0 :         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
     743             :                          DENY_NONE, &fnum2);
     744           0 :         if (!NT_STATUS_IS_OK(status)) {
     745           0 :                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
     746             :         }
     747           0 :         if (!NT_STATUS_IS_OK(status)) {
     748           0 :                 printf("open of %s failed (%s)\n",
     749             :                        lockfname, nt_errstr(status));
     750           0 :                 return False;
     751             :         }
     752             : 
     753           0 :         for (i=0;i<torture_numops;i++) {
     754           0 :                 unsigned n = (unsigned)sys_random()%10;
     755             : 
     756           0 :                 if (i % 10 == 0) {
     757           0 :                         printf("%d\r", i); fflush(stdout);
     758             :                 }
     759           0 :                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
     760             : 
     761           0 :                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
     762           0 :                         return False;
     763             :                 }
     764             : 
     765           0 :                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
     766             :                                   DENY_ALL, &fnum);
     767           0 :                 if (!NT_STATUS_IS_OK(status)) {
     768           0 :                         printf("open failed (%s)\n", nt_errstr(status));
     769           0 :                         correct = False;
     770           0 :                         break;
     771             :                 }
     772             : 
     773           0 :                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
     774             :                                       sizeof(pid), NULL);
     775           0 :                 if (!NT_STATUS_IS_OK(status)) {
     776           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     777           0 :                         correct = False;
     778             :                 }
     779             : 
     780           0 :                 for (j=0;j<50;j++) {
     781           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
     782           0 :                                               sizeof(pid)+(j*sizeof(buf)),
     783             :                                               sizeof(buf), NULL);
     784           0 :                         if (!NT_STATUS_IS_OK(status)) {
     785           0 :                                 printf("write failed (%s)\n",
     786             :                                        nt_errstr(status));
     787           0 :                                 correct = False;
     788             :                         }
     789             :                 }
     790             : 
     791           0 :                 pid2 = 0;
     792             : 
     793           0 :                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
     794             :                                   &nread);
     795           0 :                 if (!NT_STATUS_IS_OK(status)) {
     796           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     797           0 :                         correct = false;
     798           0 :                 } else if (nread != sizeof(pid)) {
     799           0 :                         printf("read/write compare failed: "
     800             :                                "recv %ld req %ld\n", (unsigned long)nread,
     801             :                                (unsigned long)sizeof(pid));
     802           0 :                         correct = false;
     803             :                 }
     804             : 
     805           0 :                 if (pid2 != pid) {
     806           0 :                         printf("data corruption!\n");
     807           0 :                         correct = False;
     808             :                 }
     809             : 
     810           0 :                 status = cli_close(c, fnum);
     811           0 :                 if (!NT_STATUS_IS_OK(status)) {
     812           0 :                         printf("close failed (%s)\n", nt_errstr(status));
     813           0 :                         correct = False;
     814             :                 }
     815             : 
     816           0 :                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     817           0 :                 if (!NT_STATUS_IS_OK(status)) {
     818           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
     819           0 :                         correct = False;
     820             :                 }
     821             : 
     822           0 :                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
     823           0 :                 if (!NT_STATUS_IS_OK(status)) {
     824           0 :                         printf("unlock failed (%s)\n", nt_errstr(status));
     825           0 :                         correct = False;
     826             :                 }
     827             :         }
     828             : 
     829           0 :         cli_close(c, fnum2);
     830           0 :         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     831             : 
     832           0 :         printf("%d\n", i);
     833             : 
     834           0 :         return correct;
     835             : }
     836             : 
     837           0 : static bool run_torture(int dummy)
     838             : {
     839           0 :         struct cli_state *cli;
     840           0 :         bool ret;
     841             : 
     842           0 :         cli = current_cli;
     843             : 
     844           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     845             : 
     846           0 :         ret = rw_torture(cli);
     847             : 
     848           0 :         if (!torture_close_connection(cli)) {
     849           0 :                 ret = False;
     850             :         }
     851             : 
     852           0 :         return ret;
     853             : }
     854             : 
     855           0 : static bool rw_torture3(struct cli_state *c, char *lockfname)
     856             : {
     857           0 :         uint16_t fnum = (uint16_t)-1;
     858           0 :         unsigned int i = 0;
     859           0 :         char buf[131072];
     860           0 :         char buf_rd[131072];
     861           0 :         unsigned count;
     862           0 :         unsigned countprev = 0;
     863           0 :         size_t sent = 0;
     864           0 :         bool correct = True;
     865           0 :         NTSTATUS status = NT_STATUS_OK;
     866             : 
     867           0 :         srandom(1);
     868           0 :         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
     869             :         {
     870           0 :                 SIVAL(buf, i, sys_random());
     871             :         }
     872             : 
     873           0 :         if (procnum == 0)
     874             :         {
     875           0 :                 status = cli_unlink(
     876             :                         c, lockfname,
     877             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     878           0 :                 if (!NT_STATUS_IS_OK(status)) {
     879           0 :                         printf("unlink failed (%s) (normal, this file should "
     880             :                                "not exist)\n", nt_errstr(status));
     881             :                 }
     882             : 
     883           0 :                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     884             :                                   DENY_NONE, &fnum);
     885           0 :                 if (!NT_STATUS_IS_OK(status)) {
     886           0 :                         printf("first open read/write of %s failed (%s)\n",
     887             :                                         lockfname, nt_errstr(status));
     888           0 :                         return False;
     889             :                 }
     890             :         }
     891             :         else
     892             :         {
     893           0 :                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
     894             :                 {
     895           0 :                         status = cli_openx(c, lockfname, O_RDONLY, 
     896             :                                          DENY_NONE, &fnum);
     897           0 :                         if (NT_STATUS_IS_OK(status)) {
     898           0 :                                 break;
     899             :                         }
     900           0 :                         smb_msleep(10);
     901             :                 }
     902           0 :                 if (!NT_STATUS_IS_OK(status)) {
     903           0 :                         printf("second open read-only of %s failed (%s)\n",
     904             :                                         lockfname, nt_errstr(status));
     905           0 :                         return False;
     906             :                 }
     907             :         }
     908             : 
     909           0 :         i = 0;
     910           0 :         for (count = 0; count < sizeof(buf); count += sent)
     911             :         {
     912           0 :                 if (count >= countprev) {
     913           0 :                         printf("%d %8d\r", i, count);
     914           0 :                         fflush(stdout);
     915           0 :                         i++;
     916           0 :                         countprev += (sizeof(buf) / 20);
     917             :                 }
     918             : 
     919           0 :                 if (procnum == 0)
     920             :                 {
     921           0 :                         sent = ((unsigned)sys_random()%(20))+ 1;
     922           0 :                         if (sent > sizeof(buf) - count)
     923             :                         {
     924           0 :                                 sent = sizeof(buf) - count;
     925             :                         }
     926             : 
     927           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
     928             :                                               count, sent, NULL);
     929           0 :                         if (!NT_STATUS_IS_OK(status)) {
     930           0 :                                 printf("write failed (%s)\n",
     931             :                                        nt_errstr(status));
     932           0 :                                 correct = False;
     933             :                         }
     934             :                 }
     935             :                 else
     936             :                 {
     937           0 :                         status = cli_read(c, fnum, buf_rd+count, count,
     938             :                                           sizeof(buf)-count, &sent);
     939           0 :                         if(!NT_STATUS_IS_OK(status)) {
     940           0 :                                 printf("read failed offset:%d size:%ld (%s)\n",
     941             :                                        count, (unsigned long)sizeof(buf)-count,
     942             :                                        nt_errstr(status));
     943           0 :                                 correct = False;
     944           0 :                                 sent = 0;
     945           0 :                         } else if (sent > 0) {
     946           0 :                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
     947             :                                 {
     948           0 :                                         printf("read/write compare failed\n");
     949           0 :                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
     950           0 :                                         correct = False;
     951           0 :                                         break;
     952             :                                 }
     953             :                         }
     954             :                 }
     955             : 
     956             :         }
     957             : 
     958           0 :         status = cli_close(c, fnum);
     959           0 :         if (!NT_STATUS_IS_OK(status)) {
     960           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     961           0 :                 correct = False;
     962             :         }
     963             : 
     964           0 :         return correct;
     965             : }
     966             : 
     967          18 : static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     968             : {
     969          18 :         const char *lockfname = "\\torture2.lck";
     970           0 :         uint16_t fnum1;
     971           0 :         uint16_t fnum2;
     972           0 :         int i;
     973           0 :         char buf[131072];
     974           0 :         char buf_rd[131072];
     975          18 :         bool correct = True;
     976           0 :         size_t bytes_read;
     977           0 :         NTSTATUS status;
     978             : 
     979          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     980          18 :         if (!NT_STATUS_IS_OK(status)) {
     981          18 :                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
     982             :         }
     983             : 
     984          18 :         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     985             :                           DENY_NONE, &fnum1);
     986          18 :         if (!NT_STATUS_IS_OK(status)) {
     987           0 :                 printf("first open read/write of %s failed (%s)\n",
     988             :                                 lockfname, nt_errstr(status));
     989           0 :                 return False;
     990             :         }
     991             : 
     992          18 :         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
     993          18 :         if (!NT_STATUS_IS_OK(status)) {
     994           0 :                 printf("second open read-only of %s failed (%s)\n",
     995             :                                 lockfname, nt_errstr(status));
     996           0 :                 cli_close(c1, fnum1);
     997           0 :                 return False;
     998             :         }
     999             : 
    1000        1818 :         for (i = 0; i < torture_numops; i++)
    1001             :         {
    1002        1800 :                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
    1003        1800 :                 if (i % 10 == 0) {
    1004         180 :                         printf("%d\r", i); fflush(stdout);
    1005             :                 }
    1006             : 
    1007        1800 :                 generate_random_buffer((unsigned char *)buf, buf_size);
    1008             : 
    1009        1800 :                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
    1010             :                                       buf_size, NULL);
    1011        1800 :                 if (!NT_STATUS_IS_OK(status)) {
    1012           0 :                         printf("write failed (%s)\n", nt_errstr(status));
    1013           0 :                         correct = False;
    1014           0 :                         break;
    1015             :                 }
    1016             : 
    1017        1800 :                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
    1018        1800 :                 if(!NT_STATUS_IS_OK(status)) {
    1019           0 :                         printf("read failed (%s)\n", nt_errstr(status));
    1020           0 :                         correct = false;
    1021           0 :                         break;
    1022        1800 :                 } else if (bytes_read != buf_size) {
    1023           0 :                         printf("read failed\n");
    1024           0 :                         printf("read %ld, expected %ld\n",
    1025             :                                (unsigned long)bytes_read,
    1026             :                                (unsigned long)buf_size); 
    1027           0 :                         correct = False;
    1028           0 :                         break;
    1029             :                 }
    1030             : 
    1031        1800 :                 if (memcmp(buf_rd, buf, buf_size) != 0)
    1032             :                 {
    1033           0 :                         printf("read/write compare failed\n");
    1034           0 :                         correct = False;
    1035           0 :                         break;
    1036             :                 }
    1037             :         }
    1038             : 
    1039          18 :         status = cli_close(c2, fnum2);
    1040          18 :         if (!NT_STATUS_IS_OK(status)) {
    1041           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1042           0 :                 correct = False;
    1043             :         }
    1044             : 
    1045          18 :         status = cli_close(c1, fnum1);
    1046          18 :         if (!NT_STATUS_IS_OK(status)) {
    1047           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1048           0 :                 correct = False;
    1049             :         }
    1050             : 
    1051          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1052          18 :         if (!NT_STATUS_IS_OK(status)) {
    1053           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1054           0 :                 correct = False;
    1055             :         }
    1056             : 
    1057          18 :         return correct;
    1058             : }
    1059             : 
    1060           9 : static bool run_readwritetest(int dummy)
    1061             : {
    1062           0 :         struct cli_state *cli1, *cli2;
    1063           9 :         bool test1, test2 = False;
    1064             : 
    1065           9 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1066           0 :                 return False;
    1067             :         }
    1068           9 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1069           9 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1070             : 
    1071           9 :         printf("starting readwritetest\n");
    1072             : 
    1073           9 :         test1 = rw_torture2(cli1, cli2);
    1074           9 :         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
    1075             : 
    1076           9 :         if (test1) {
    1077           9 :                 test2 = rw_torture2(cli1, cli1);
    1078           9 :                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
    1079             :         }
    1080             : 
    1081           9 :         if (!torture_close_connection(cli1)) {
    1082           0 :                 test1 = False;
    1083             :         }
    1084             : 
    1085           9 :         if (!torture_close_connection(cli2)) {
    1086           0 :                 test2 = False;
    1087             :         }
    1088             : 
    1089           9 :         return (test1 && test2);
    1090             : }
    1091             : 
    1092           0 : static bool run_readwritemulti(int dummy)
    1093             : {
    1094           0 :         struct cli_state *cli;
    1095           0 :         bool test;
    1096             : 
    1097           0 :         cli = current_cli;
    1098             : 
    1099           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1100             : 
    1101           0 :         printf("run_readwritemulti: fname %s\n", randomfname);
    1102           0 :         test = rw_torture3(cli, randomfname);
    1103             : 
    1104           0 :         if (!torture_close_connection(cli)) {
    1105           0 :                 test = False;
    1106             :         }
    1107             : 
    1108           0 :         return test;
    1109             : }
    1110             : 
    1111          14 : static bool run_readwritelarge_internal(void)
    1112             : {
    1113           0 :         static struct cli_state *cli1;
    1114           0 :         uint16_t fnum1;
    1115          14 :         const char *lockfname = "\\large.dat";
    1116           0 :         off_t fsize;
    1117           0 :         char buf[126*1024];
    1118          14 :         bool correct = True;
    1119           0 :         NTSTATUS status;
    1120             : 
    1121          14 :         if (!torture_open_connection(&cli1, 0)) {
    1122           0 :                 return False;
    1123             :         }
    1124          14 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1125          14 :         memset(buf,'\0',sizeof(buf));
    1126             : 
    1127          14 :         printf("starting readwritelarge_internal\n");
    1128             : 
    1129          14 :         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1130             : 
    1131          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1132             :                           DENY_NONE, &fnum1);
    1133          14 :         if (!NT_STATUS_IS_OK(status)) {
    1134           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1135           0 :                 return False;
    1136             :         }
    1137             : 
    1138          14 :         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
    1139             : 
    1140          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1141             :                                      NULL, NULL, NULL);
    1142          14 :         if (!NT_STATUS_IS_OK(status)) {
    1143           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1144           0 :                 correct = False;
    1145             :         }
    1146             : 
    1147          14 :         if (fsize == sizeof(buf))
    1148          14 :                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
    1149             :                        (unsigned long)fsize);
    1150             :         else {
    1151           0 :                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
    1152             :                        (unsigned long)fsize);
    1153           0 :                 correct = False;
    1154             :         }
    1155             : 
    1156          14 :         status = cli_close(cli1, fnum1);
    1157          14 :         if (!NT_STATUS_IS_OK(status)) {
    1158           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1159           0 :                 correct = False;
    1160             :         }
    1161             : 
    1162          14 :         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1163          14 :         if (!NT_STATUS_IS_OK(status)) {
    1164           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1165           0 :                 correct = False;
    1166             :         }
    1167             : 
    1168          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1169             :                           DENY_NONE, &fnum1);
    1170          14 :         if (!NT_STATUS_IS_OK(status)) {
    1171           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1172           0 :                 return False;
    1173             :         }
    1174             : 
    1175          14 :         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
    1176             : 
    1177          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1178             :                                      NULL, NULL, NULL);
    1179          14 :         if (!NT_STATUS_IS_OK(status)) {
    1180           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1181           0 :                 correct = False;
    1182             :         }
    1183             : 
    1184          14 :         if (fsize == sizeof(buf))
    1185          14 :                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
    1186             :                        (unsigned long)fsize);
    1187             :         else {
    1188           0 :                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
    1189             :                        (unsigned long)fsize);
    1190           0 :                 correct = False;
    1191             :         }
    1192             : 
    1193          14 :         status = cli_close(cli1, fnum1);
    1194          14 :         if (!NT_STATUS_IS_OK(status)) {
    1195           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1196           0 :                 correct = False;
    1197             :         }
    1198             : 
    1199          14 :         if (!torture_close_connection(cli1)) {
    1200           0 :                 correct = False;
    1201             :         }
    1202          14 :         return correct;
    1203             : }
    1204             : 
    1205           9 : static bool run_readwritelarge(int dummy)
    1206             : {
    1207           9 :         return run_readwritelarge_internal();
    1208             : }
    1209             : 
    1210           5 : static bool run_readwritelarge_signtest(int dummy)
    1211             : {
    1212           0 :         bool ret;
    1213           5 :         signing_state = SMB_SIGNING_REQUIRED;
    1214           5 :         ret = run_readwritelarge_internal();
    1215           5 :         signing_state = SMB_SIGNING_DEFAULT;
    1216           5 :         return ret;
    1217             : }
    1218             : 
    1219             : int line_count = 0;
    1220             : int nbio_id;
    1221             : 
    1222             : #define ival(s) strtol(s, NULL, 0)
    1223             : 
    1224             : /* run a test that simulates an approximate netbench client load */
    1225           0 : static bool run_netbench(int client)
    1226             : {
    1227           0 :         struct cli_state *cli;
    1228           0 :         int i;
    1229           0 :         char line[1024];
    1230           0 :         char cname[20];
    1231           0 :         FILE *f;
    1232           0 :         const char *params[20];
    1233           0 :         bool correct = True;
    1234             : 
    1235           0 :         cli = current_cli;
    1236             : 
    1237           0 :         nbio_id = client;
    1238             : 
    1239           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1240             : 
    1241           0 :         nb_setup(cli);
    1242             : 
    1243           0 :         slprintf(cname,sizeof(cname)-1, "client%d", client);
    1244             : 
    1245           0 :         f = fopen(client_txt, "r");
    1246             : 
    1247           0 :         if (!f) {
    1248           0 :                 perror(client_txt);
    1249           0 :                 return False;
    1250             :         }
    1251             : 
    1252           0 :         while (fgets(line, sizeof(line)-1, f)) {
    1253           0 :                 char *saveptr;
    1254           0 :                 line_count++;
    1255             : 
    1256           0 :                 line[strlen(line)-1] = 0;
    1257             : 
    1258             :                 /* printf("[%d] %s\n", line_count, line); */
    1259             : 
    1260           0 :                 all_string_sub(line,"client1", cname, sizeof(line));
    1261             : 
    1262             :                 /* parse the command parameters */
    1263           0 :                 params[0] = strtok_r(line, " ", &saveptr);
    1264           0 :                 i = 0;
    1265           0 :                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
    1266             : 
    1267           0 :                 params[i] = "";
    1268             : 
    1269           0 :                 if (i < 2) continue;
    1270             : 
    1271           0 :                 if (!strncmp(params[0],"SMB", 3)) {
    1272           0 :                         printf("ERROR: You are using a dbench 1 load file\n");
    1273           0 :                         exit(1);
    1274             :                 }
    1275             : 
    1276           0 :                 if (!strcmp(params[0],"NTCreateX")) {
    1277           0 :                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
    1278           0 :                                    ival(params[4]));
    1279           0 :                 } else if (!strcmp(params[0],"Close")) {
    1280           0 :                         nb_close(ival(params[1]));
    1281           0 :                 } else if (!strcmp(params[0],"Rename")) {
    1282           0 :                         nb_rename(params[1], params[2]);
    1283           0 :                 } else if (!strcmp(params[0],"Unlink")) {
    1284           0 :                         nb_unlink(params[1]);
    1285           0 :                 } else if (!strcmp(params[0],"Deltree")) {
    1286           0 :                         nb_deltree(params[1]);
    1287           0 :                 } else if (!strcmp(params[0],"Rmdir")) {
    1288           0 :                         nb_rmdir(params[1]);
    1289           0 :                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
    1290           0 :                         nb_qpathinfo(params[1]);
    1291           0 :                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
    1292           0 :                         nb_qfileinfo(ival(params[1]));
    1293           0 :                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
    1294           0 :                         nb_qfsinfo(ival(params[1]));
    1295           0 :                 } else if (!strcmp(params[0],"FIND_FIRST")) {
    1296           0 :                         nb_findfirst(params[1]);
    1297           0 :                 } else if (!strcmp(params[0],"WriteX")) {
    1298           0 :                         nb_writex(ival(params[1]), 
    1299           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1300           0 :                 } else if (!strcmp(params[0],"ReadX")) {
    1301           0 :                         nb_readx(ival(params[1]), 
    1302           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1303           0 :                 } else if (!strcmp(params[0],"Flush")) {
    1304           0 :                         nb_flush(ival(params[1]));
    1305             :                 } else {
    1306           0 :                         printf("Unknown operation %s\n", params[0]);
    1307           0 :                         exit(1);
    1308             :                 }
    1309             :         }
    1310           0 :         fclose(f);
    1311             : 
    1312           0 :         nb_cleanup();
    1313             : 
    1314           0 :         if (!torture_close_connection(cli)) {
    1315           0 :                 correct = False;
    1316             :         }
    1317             : 
    1318           0 :         return correct;
    1319             : }
    1320             : 
    1321             : 
    1322             : /* run a test that simulates an approximate netbench client load */
    1323           0 : static bool run_nbench(int dummy)
    1324             : {
    1325           0 :         double t;
    1326           0 :         bool correct = True;
    1327             : 
    1328           0 :         nbio_shmem(torture_nprocs);
    1329             : 
    1330           0 :         nbio_id = -1;
    1331             : 
    1332           0 :         signal(SIGALRM, nb_alarm);
    1333           0 :         alarm(1);
    1334           0 :         t = create_procs(run_netbench, &correct);
    1335           0 :         alarm(0);
    1336             : 
    1337           0 :         printf("\nThroughput %g MB/sec\n", 
    1338           0 :                1.0e-6 * nbio_total() / t);
    1339           0 :         return correct;
    1340             : }
    1341             : 
    1342             : 
    1343             : /*
    1344             :   This test checks for two things:
    1345             : 
    1346             :   1) correct support for retaining locks over a close (ie. the server
    1347             :      must not use posix semantics)
    1348             :   2) support for lock timeouts
    1349             :  */
    1350           5 : static bool run_locktest1(int dummy)
    1351             : {
    1352           0 :         struct cli_state *cli1, *cli2;
    1353           5 :         const char *fname = "\\lockt1.lck";
    1354           0 :         uint16_t fnum1, fnum2, fnum3;
    1355           0 :         time_t t1, t2;
    1356           0 :         unsigned lock_timeout;
    1357           0 :         NTSTATUS status;
    1358             : 
    1359           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1360           0 :                 return False;
    1361             :         }
    1362           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1363           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1364             : 
    1365           5 :         printf("starting locktest1\n");
    1366             : 
    1367           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1368             : 
    1369           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1370             :                           &fnum1);
    1371           5 :         if (!NT_STATUS_IS_OK(status)) {
    1372           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1373           0 :                 return False;
    1374             :         }
    1375             : 
    1376           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
    1377           5 :         if (!NT_STATUS_IS_OK(status)) {
    1378           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1379           0 :                 return False;
    1380             :         }
    1381             : 
    1382           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
    1383           5 :         if (!NT_STATUS_IS_OK(status)) {
    1384           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1385           0 :                 return False;
    1386             :         }
    1387             : 
    1388           5 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    1389           5 :         if (!NT_STATUS_IS_OK(status)) {
    1390           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1391           0 :                 return false;
    1392             :         }
    1393             : 
    1394           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1395           5 :         if (NT_STATUS_IS_OK(status)) {
    1396           0 :                 printf("lock2 succeeded! This is a locking bug\n");
    1397           0 :                 return false;
    1398             :         } else {
    1399           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1400           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1401           0 :                         return false;
    1402             :                 }
    1403             :         }
    1404             : 
    1405           5 :         lock_timeout = (1 + (random() % 20));
    1406           5 :         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
    1407           5 :         t1 = time(NULL);
    1408           5 :         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
    1409           5 :         if (NT_STATUS_IS_OK(status)) {
    1410           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1411           0 :                 return false;
    1412             :         } else {
    1413           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1414           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1415           0 :                         return false;
    1416             :                 }
    1417             :         }
    1418           5 :         t2 = time(NULL);
    1419             : 
    1420           5 :         if (ABS(t2 - t1) < lock_timeout-1) {
    1421           0 :                 printf("error: This server appears not to support timed lock requests\n");
    1422             :         }
    1423             : 
    1424           5 :         printf("server slept for %u seconds for a %u second timeout\n",
    1425             :                (unsigned int)(t2-t1), lock_timeout);
    1426             : 
    1427           5 :         status = cli_close(cli1, fnum2);
    1428           5 :         if (!NT_STATUS_IS_OK(status)) {
    1429           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1430           0 :                 return False;
    1431             :         }
    1432             : 
    1433           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1434           5 :         if (NT_STATUS_IS_OK(status)) {
    1435           0 :                 printf("lock4 succeeded! This is a locking bug\n");
    1436           0 :                 return false;
    1437             :         } else {
    1438           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1439           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1440           0 :                         return false;
    1441             :                 }
    1442             :         }
    1443             : 
    1444           5 :         status = cli_close(cli1, fnum1);
    1445           5 :         if (!NT_STATUS_IS_OK(status)) {
    1446           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1447           0 :                 return False;
    1448             :         }
    1449             : 
    1450           5 :         status = cli_close(cli2, fnum3);
    1451           5 :         if (!NT_STATUS_IS_OK(status)) {
    1452           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1453           0 :                 return False;
    1454             :         }
    1455             : 
    1456           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1457           5 :         if (!NT_STATUS_IS_OK(status)) {
    1458           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1459           0 :                 return False;
    1460             :         }
    1461             : 
    1462             : 
    1463           5 :         if (!torture_close_connection(cli1)) {
    1464           0 :                 return False;
    1465             :         }
    1466             : 
    1467           5 :         if (!torture_close_connection(cli2)) {
    1468           0 :                 return False;
    1469             :         }
    1470             : 
    1471           5 :         printf("Passed locktest1\n");
    1472           5 :         return True;
    1473             : }
    1474             : 
    1475             : /*
    1476             :   this checks to see if a secondary tconx can use open files from an
    1477             :   earlier tconx
    1478             :  */
    1479           5 : static bool run_tcon_test(int dummy)
    1480             : {
    1481           0 :         static struct cli_state *cli;
    1482           5 :         const char *fname = "\\tcontest.tmp";
    1483           0 :         uint16_t fnum1;
    1484           0 :         uint32_t cnum1, cnum2, cnum3;
    1485           5 :         struct smbXcli_tcon *orig_tcon = NULL;
    1486           5 :         char *orig_share = NULL;
    1487           0 :         uint16_t vuid1, vuid2;
    1488           0 :         char buf[4];
    1489           5 :         bool ret = True;
    1490           0 :         NTSTATUS status;
    1491             : 
    1492           5 :         memset(buf, '\0', sizeof(buf));
    1493             : 
    1494           5 :         if (!torture_open_connection(&cli, 0)) {
    1495           0 :                 return False;
    1496             :         }
    1497           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1498             : 
    1499           5 :         printf("starting tcontest\n");
    1500             : 
    1501           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1502             : 
    1503           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1504           5 :         if (!NT_STATUS_IS_OK(status)) {
    1505           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1506           0 :                 return False;
    1507             :         }
    1508             : 
    1509           5 :         cnum1 = cli_state_get_tid(cli);
    1510           5 :         vuid1 = cli_state_get_uid(cli);
    1511             : 
    1512           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1513           5 :         if (!NT_STATUS_IS_OK(status)) {
    1514           0 :                 printf("initial write failed (%s)", nt_errstr(status));
    1515           0 :                 return False;
    1516             :         }
    1517             : 
    1518           5 :         cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
    1519             : 
    1520           5 :         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
    1521           5 :         if (!NT_STATUS_IS_OK(status)) {
    1522           0 :                 printf("%s refused 2nd tree connect (%s)\n", host,
    1523             :                        nt_errstr(status));
    1524           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1525           0 :                 cli_shutdown(cli);
    1526           0 :                 return False;
    1527             :         }
    1528             : 
    1529           5 :         cnum2 = cli_state_get_tid(cli);
    1530           5 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
    1531           5 :         vuid2 = cli_state_get_uid(cli) + 1;
    1532             : 
    1533             :         /* try a write with the wrong tid */
    1534           5 :         cli_state_set_tid(cli, cnum2);
    1535             : 
    1536           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1537           5 :         if (NT_STATUS_IS_OK(status)) {
    1538           0 :                 printf("* server allows write with wrong TID\n");
    1539           0 :                 ret = False;
    1540             :         } else {
    1541           5 :                 printf("server fails write with wrong TID : %s\n",
    1542             :                        nt_errstr(status));
    1543             :         }
    1544             : 
    1545             : 
    1546             :         /* try a write with an invalid tid */
    1547           5 :         cli_state_set_tid(cli, cnum3);
    1548             : 
    1549           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1550           5 :         if (NT_STATUS_IS_OK(status)) {
    1551           0 :                 printf("* server allows write with invalid TID\n");
    1552           0 :                 ret = False;
    1553             :         } else {
    1554           5 :                 printf("server fails write with invalid TID : %s\n",
    1555             :                        nt_errstr(status));
    1556             :         }
    1557             : 
    1558             :         /* try a write with an invalid vuid */
    1559           5 :         cli_state_set_uid(cli, vuid2);
    1560           5 :         cli_state_set_tid(cli, cnum1);
    1561             : 
    1562           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1563           5 :         if (NT_STATUS_IS_OK(status)) {
    1564           0 :                 printf("* server allows write with invalid VUID\n");
    1565           0 :                 ret = False;
    1566             :         } else {
    1567           5 :                 printf("server fails write with invalid VUID : %s\n",
    1568             :                        nt_errstr(status));
    1569             :         }
    1570             : 
    1571           5 :         cli_state_set_tid(cli, cnum1);
    1572           5 :         cli_state_set_uid(cli, vuid1);
    1573             : 
    1574           5 :         status = cli_close(cli, fnum1);
    1575           5 :         if (!NT_STATUS_IS_OK(status)) {
    1576           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1577           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1578           0 :                 cli_shutdown(cli);
    1579           0 :                 return False;
    1580             :         }
    1581             : 
    1582           5 :         cli_state_set_tid(cli, cnum2);
    1583             : 
    1584           5 :         status = cli_tdis(cli);
    1585           5 :         if (!NT_STATUS_IS_OK(status)) {
    1586           0 :                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
    1587           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1588           0 :                 cli_shutdown(cli);
    1589           0 :                 return False;
    1590             :         }
    1591             : 
    1592           5 :         cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1593             : 
    1594           5 :         cli_state_set_tid(cli, cnum1);
    1595             : 
    1596           5 :         if (!torture_close_connection(cli)) {
    1597           0 :                 return False;
    1598             :         }
    1599             : 
    1600           5 :         return ret;
    1601             : }
    1602             : 
    1603             : 
    1604             : /*
    1605             :  checks for old style tcon support
    1606             :  */
    1607           5 : static bool run_tcon2_test(int dummy)
    1608             : {
    1609           0 :         static struct cli_state *cli;
    1610           0 :         uint16_t cnum, max_xmit;
    1611           0 :         char *service;
    1612           0 :         NTSTATUS status;
    1613             : 
    1614           5 :         if (!torture_open_connection(&cli, 0)) {
    1615           0 :                 return False;
    1616             :         }
    1617           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1618             : 
    1619           5 :         printf("starting tcon2 test\n");
    1620             : 
    1621           5 :         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
    1622           0 :                 return false;
    1623             :         }
    1624             : 
    1625           5 :         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
    1626             : 
    1627           5 :         SAFE_FREE(service);
    1628             : 
    1629           5 :         if (!NT_STATUS_IS_OK(status)) {
    1630           5 :                 printf("tcon2 failed : %s\n", nt_errstr(status));
    1631             :         } else {
    1632           0 :                 printf("tcon OK : max_xmit=%d cnum=%d\n",
    1633             :                        (int)max_xmit, (int)cnum);
    1634             :         }
    1635             : 
    1636           5 :         if (!torture_close_connection(cli)) {
    1637           0 :                 return False;
    1638             :         }
    1639             : 
    1640           5 :         printf("Passed tcon2 test\n");
    1641           5 :         return True;
    1642             : }
    1643             : 
    1644          50 : static bool tcon_devtest(struct cli_state *cli,
    1645             :                          const char *myshare, const char *devtype,
    1646             :                          const char *return_devtype,
    1647             :                          NTSTATUS expected_error)
    1648             : {
    1649           0 :         NTSTATUS status;
    1650           0 :         bool ret;
    1651             : 
    1652          50 :         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
    1653             : 
    1654          50 :         if (NT_STATUS_IS_OK(expected_error)) {
    1655          20 :                 if (NT_STATUS_IS_OK(status)) {
    1656          40 :                         if (return_devtype != NULL &&
    1657          20 :                             strequal(cli->dev, return_devtype)) {
    1658          20 :                                 ret = True;
    1659             :                         } else { 
    1660           0 :                                 printf("tconX to share %s with type %s "
    1661             :                                        "succeeded but returned the wrong "
    1662             :                                        "device type (got [%s] but should have got [%s])\n",
    1663             :                                        myshare, devtype, cli->dev, return_devtype);
    1664           0 :                                 ret = False;
    1665             :                         }
    1666             :                 } else {
    1667           0 :                         printf("tconX to share %s with type %s "
    1668             :                                "should have succeeded but failed\n",
    1669             :                                myshare, devtype);
    1670           0 :                         ret = False;
    1671             :                 }
    1672          20 :                 cli_tdis(cli);
    1673             :         } else {
    1674          30 :                 if (NT_STATUS_IS_OK(status)) {
    1675           0 :                         printf("tconx to share %s with type %s "
    1676             :                                "should have failed but succeeded\n",
    1677             :                                myshare, devtype);
    1678           0 :                         ret = False;
    1679             :                 } else {
    1680          30 :                         if (NT_STATUS_EQUAL(status, expected_error)) {
    1681          30 :                                 ret = True;
    1682             :                         } else {
    1683           0 :                                 printf("Returned unexpected error\n");
    1684           0 :                                 ret = False;
    1685             :                         }
    1686             :                 }
    1687             :         }
    1688          50 :         return ret;
    1689             : }
    1690             : 
    1691             : /*
    1692             :  checks for correct tconX support
    1693             :  */
    1694           5 : static bool run_tcon_devtype_test(int dummy)
    1695             : {
    1696           0 :         static struct cli_state *cli1 = NULL;
    1697           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
    1698           0 :         NTSTATUS status;
    1699           5 :         bool ret = True;
    1700             : 
    1701           5 :         status = cli_full_connection_creds(&cli1,
    1702             :                                            myname,
    1703             :                                            host,
    1704             :                                            NULL, /* dest_ss */
    1705             :                                            port_to_use,
    1706             :                                            NULL, /* service */
    1707             :                                            NULL, /* service_type */
    1708             :                                            torture_creds,
    1709             :                                            flags);
    1710             : 
    1711           5 :         if (!NT_STATUS_IS_OK(status)) {
    1712           0 :                 printf("could not open connection\n");
    1713           0 :                 return False;
    1714             :         }
    1715             : 
    1716           5 :         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1717           0 :                 ret = False;
    1718             : 
    1719           5 :         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
    1720           0 :                 ret = False;
    1721             : 
    1722           5 :         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1723           0 :                 ret = False;
    1724             : 
    1725           5 :         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
    1726           0 :                 ret = False;
    1727             : 
    1728           5 :         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1729           0 :                 ret = False;
    1730             : 
    1731           5 :         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
    1732           0 :                 ret = False;
    1733             : 
    1734           5 :         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
    1735           0 :                 ret = False;
    1736             : 
    1737           5 :         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1738           0 :                 ret = False;
    1739             : 
    1740           5 :         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1741           0 :                 ret = False;
    1742             : 
    1743           5 :         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1744           0 :                 ret = False;
    1745             : 
    1746           5 :         cli_shutdown(cli1);
    1747             : 
    1748           5 :         if (ret)
    1749           5 :                 printf("Passed tcondevtest\n");
    1750             : 
    1751           5 :         return ret;
    1752             : }
    1753             : 
    1754             : 
    1755             : /*
    1756             :   This test checks that 
    1757             : 
    1758             :   1) the server supports multiple locking contexts on the one SMB
    1759             :   connection, distinguished by PID.  
    1760             : 
    1761             :   2) the server correctly fails overlapping locks made by the same PID (this
    1762             :      goes against POSIX behaviour, which is why it is tricky to implement)
    1763             : 
    1764             :   3) the server denies unlock requests by an incorrect client PID
    1765             : */
    1766           5 : static bool run_locktest2(int dummy)
    1767             : {
    1768           0 :         static struct cli_state *cli;
    1769           5 :         const char *fname = "\\lockt2.lck";
    1770           0 :         uint16_t fnum1, fnum2, fnum3;
    1771           5 :         bool correct = True;
    1772           0 :         NTSTATUS status;
    1773             : 
    1774           5 :         if (!torture_open_connection(&cli, 0)) {
    1775           0 :                 return False;
    1776             :         }
    1777             : 
    1778           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1779             : 
    1780           5 :         printf("starting locktest2\n");
    1781             : 
    1782           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1783             : 
    1784           5 :         cli_setpid(cli, 1);
    1785             : 
    1786           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1787           5 :         if (!NT_STATUS_IS_OK(status)) {
    1788           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1789           0 :                 return False;
    1790             :         }
    1791             : 
    1792           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
    1793           5 :         if (!NT_STATUS_IS_OK(status)) {
    1794           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1795           0 :                 return False;
    1796             :         }
    1797             : 
    1798           5 :         cli_setpid(cli, 2);
    1799             : 
    1800           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
    1801           5 :         if (!NT_STATUS_IS_OK(status)) {
    1802           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1803           0 :                 return False;
    1804             :         }
    1805             : 
    1806           5 :         cli_setpid(cli, 1);
    1807             : 
    1808           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1809           5 :         if (!NT_STATUS_IS_OK(status)) {
    1810           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1811           0 :                 return false;
    1812             :         }
    1813             : 
    1814           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1815           5 :         if (NT_STATUS_IS_OK(status)) {
    1816           0 :                 printf("WRITE lock1 succeeded! This is a locking bug\n");
    1817           0 :                 correct = false;
    1818             :         } else {
    1819           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1820           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1821           0 :                         return false;
    1822             :                 }
    1823             :         }
    1824             : 
    1825           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
    1826           5 :         if (NT_STATUS_IS_OK(status)) {
    1827           0 :                 printf("WRITE lock2 succeeded! This is a locking bug\n");
    1828           0 :                 correct = false;
    1829             :         } else {
    1830           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1831           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1832           0 :                         return false;
    1833             :                 }
    1834             :         }
    1835             : 
    1836           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
    1837           5 :         if (NT_STATUS_IS_OK(status)) {
    1838           0 :                 printf("READ lock2 succeeded! This is a locking bug\n");
    1839           0 :                 correct = false;
    1840             :         } else {
    1841           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1842           5 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
    1843           0 :                         return false;
    1844             :                 }
    1845             :         }
    1846             : 
    1847           5 :         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
    1848           5 :         if (!NT_STATUS_IS_OK(status)) {
    1849           0 :                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
    1850             :         }
    1851           5 :         cli_setpid(cli, 2);
    1852           5 :         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
    1853           0 :                 printf("unlock at 100 succeeded! This is a locking bug\n");
    1854           0 :                 correct = False;
    1855             :         }
    1856             : 
    1857           5 :         status = cli_unlock(cli, fnum1, 0, 4);
    1858           5 :         if (NT_STATUS_IS_OK(status)) {
    1859           0 :                 printf("unlock1 succeeded! This is a locking bug\n");
    1860           0 :                 correct = false;
    1861             :         } else {
    1862           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1863           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1864           0 :                         return false;
    1865             :                 }
    1866             :         }
    1867             : 
    1868           5 :         status = cli_unlock(cli, fnum1, 0, 8);
    1869           5 :         if (NT_STATUS_IS_OK(status)) {
    1870           0 :                 printf("unlock2 succeeded! This is a locking bug\n");
    1871           0 :                 correct = false;
    1872             :         } else {
    1873           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1874           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1875           0 :                         return false;
    1876             :                 }
    1877             :         }
    1878             : 
    1879           5 :         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
    1880           5 :         if (NT_STATUS_IS_OK(status)) {
    1881           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1882           0 :                 correct = false;
    1883             :         } else {
    1884           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1885           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1886           0 :                         return false;
    1887             :                 }
    1888             :         }
    1889             : 
    1890           5 :         cli_setpid(cli, 1);
    1891             : 
    1892           5 :         status = cli_close(cli, fnum1);
    1893           5 :         if (!NT_STATUS_IS_OK(status)) {
    1894           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1895           0 :                 return False;
    1896             :         }
    1897             : 
    1898           5 :         status = cli_close(cli, fnum2);
    1899           5 :         if (!NT_STATUS_IS_OK(status)) {
    1900           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1901           0 :                 return False;
    1902             :         }
    1903             : 
    1904           5 :         status = cli_close(cli, fnum3);
    1905           5 :         if (!NT_STATUS_IS_OK(status)) {
    1906           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1907           0 :                 return False;
    1908             :         }
    1909             : 
    1910           5 :         if (!torture_close_connection(cli)) {
    1911           0 :                 correct = False;
    1912             :         }
    1913             : 
    1914           5 :         printf("locktest2 finished\n");
    1915             : 
    1916           5 :         return correct;
    1917             : }
    1918             : 
    1919             : 
    1920             : /*
    1921             :   This test checks that 
    1922             : 
    1923             :   1) the server supports the full offset range in lock requests
    1924             : */
    1925           5 : static bool run_locktest3(int dummy)
    1926             : {
    1927           0 :         static struct cli_state *cli1, *cli2;
    1928           5 :         const char *fname = "\\lockt3.lck";
    1929           0 :         uint16_t fnum1, fnum2;
    1930           0 :         int i;
    1931           0 :         uint32_t offset;
    1932           5 :         bool correct = True;
    1933           0 :         NTSTATUS status;
    1934             : 
    1935             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
    1936             : 
    1937           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1938           0 :                 return False;
    1939             :         }
    1940           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1941           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1942             : 
    1943           5 :         printf("starting locktest3\n");
    1944             : 
    1945           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1946             : 
    1947           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1948             :                          &fnum1);
    1949           5 :         if (!NT_STATUS_IS_OK(status)) {
    1950           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1951           0 :                 return False;
    1952             :         }
    1953             : 
    1954           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1955           5 :         if (!NT_STATUS_IS_OK(status)) {
    1956           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1957           0 :                 return False;
    1958             :         }
    1959             : 
    1960         505 :         for (offset=i=0;i<torture_numops;i++) {
    1961         500 :                 NEXT_OFFSET;
    1962             : 
    1963         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1964         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1965           0 :                         printf("lock1 %d failed (%s)\n", 
    1966             :                                i,
    1967             :                                nt_errstr(status));
    1968           0 :                         return False;
    1969             :                 }
    1970             : 
    1971         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1972         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1973           0 :                         printf("lock2 %d failed (%s)\n", 
    1974             :                                i,
    1975             :                                nt_errstr(status));
    1976           0 :                         return False;
    1977             :                 }
    1978             :         }
    1979             : 
    1980         505 :         for (offset=i=0;i<torture_numops;i++) {
    1981         500 :                 NEXT_OFFSET;
    1982             : 
    1983         500 :                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
    1984         500 :                 if (NT_STATUS_IS_OK(status)) {
    1985           0 :                         printf("error: lock1 %d succeeded!\n", i);
    1986           0 :                         return False;
    1987             :                 }
    1988             : 
    1989         500 :                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
    1990         500 :                 if (NT_STATUS_IS_OK(status)) {
    1991           0 :                         printf("error: lock2 %d succeeded!\n", i);
    1992           0 :                         return False;
    1993             :                 }
    1994             : 
    1995         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1996         500 :                 if (NT_STATUS_IS_OK(status)) {
    1997           0 :                         printf("error: lock3 %d succeeded!\n", i);
    1998           0 :                         return False;
    1999             :                 }
    2000             : 
    2001         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    2002         500 :                 if (NT_STATUS_IS_OK(status)) {
    2003           0 :                         printf("error: lock4 %d succeeded!\n", i);
    2004           0 :                         return False;
    2005             :                 }
    2006             :         }
    2007             : 
    2008         505 :         for (offset=i=0;i<torture_numops;i++) {
    2009         500 :                 NEXT_OFFSET;
    2010             : 
    2011         500 :                 status = cli_unlock(cli1, fnum1, offset-1, 1);
    2012         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2013           0 :                         printf("unlock1 %d failed (%s)\n", 
    2014             :                                i,
    2015             :                                nt_errstr(status));
    2016           0 :                         return False;
    2017             :                 }
    2018             : 
    2019         500 :                 status = cli_unlock(cli2, fnum2, offset-2, 1);
    2020         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2021           0 :                         printf("unlock2 %d failed (%s)\n", 
    2022             :                                i,
    2023             :                                nt_errstr(status));
    2024           0 :                         return False;
    2025             :                 }
    2026             :         }
    2027             : 
    2028           5 :         status = cli_close(cli1, fnum1);
    2029           5 :         if (!NT_STATUS_IS_OK(status)) {
    2030           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    2031           0 :                 return False;
    2032             :         }
    2033             : 
    2034           5 :         status = cli_close(cli2, fnum2);
    2035           5 :         if (!NT_STATUS_IS_OK(status)) {
    2036           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    2037           0 :                 return False;
    2038             :         }
    2039             : 
    2040           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2041           5 :         if (!NT_STATUS_IS_OK(status)) {
    2042           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    2043           0 :                 return False;
    2044             :         }
    2045             : 
    2046           5 :         if (!torture_close_connection(cli1)) {
    2047           0 :                 correct = False;
    2048             :         }
    2049             : 
    2050           5 :         if (!torture_close_connection(cli2)) {
    2051           0 :                 correct = False;
    2052             :         }
    2053             : 
    2054           5 :         printf("finished locktest3\n");
    2055             : 
    2056           5 :         return correct;
    2057             : }
    2058             : 
    2059          40 : static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
    2060             :                            char *buf, off_t offset, size_t size,
    2061             :                            size_t *nread, size_t expect)
    2062             : {
    2063           0 :         NTSTATUS status;
    2064           0 :         size_t l_nread;
    2065             : 
    2066          40 :         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
    2067             : 
    2068          40 :         if(!NT_STATUS_IS_OK(status)) {
    2069          20 :                 return false;
    2070          20 :         } else if (l_nread != expect) {
    2071           0 :                 return false;
    2072             :         }
    2073             : 
    2074          20 :         if (nread) {
    2075           0 :                 *nread = l_nread;
    2076             :         }
    2077             : 
    2078          20 :         return true;
    2079             : }
    2080             : 
    2081             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
    2082             :         printf("** "); correct = False; \
    2083             :         }
    2084             : 
    2085             : /*
    2086             :   looks at overlapping locks
    2087             : */
    2088           5 : static bool run_locktest4(int dummy)
    2089             : {
    2090           0 :         static struct cli_state *cli1, *cli2;
    2091           5 :         const char *fname = "\\lockt4.lck";
    2092           0 :         uint16_t fnum1, fnum2, f;
    2093           0 :         bool ret;
    2094           0 :         char buf[1000];
    2095           5 :         bool correct = True;
    2096           0 :         NTSTATUS status;
    2097             : 
    2098           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2099           0 :                 return False;
    2100             :         }
    2101             : 
    2102           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2103           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2104             : 
    2105           5 :         printf("starting locktest4\n");
    2106             : 
    2107           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2108             : 
    2109           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2110           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2111             : 
    2112           5 :         memset(buf, 0, sizeof(buf));
    2113             : 
    2114           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2115             :                               NULL);
    2116           5 :         if (!NT_STATUS_IS_OK(status)) {
    2117           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2118           0 :                 correct = False;
    2119           0 :                 goto fail;
    2120             :         }
    2121             : 
    2122          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2123           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
    2124           5 :         EXPECTED(ret, False);
    2125           5 :         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
    2126             : 
    2127          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
    2128           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
    2129           5 :         EXPECTED(ret, True);
    2130           5 :         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
    2131             : 
    2132          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
    2133           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
    2134           5 :         EXPECTED(ret, False);
    2135           5 :         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
    2136             : 
    2137          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
    2138           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
    2139           5 :         EXPECTED(ret, True);
    2140           5 :         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
    2141             : 
    2142           5 :         ret = (cli_setpid(cli1, 1),
    2143          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
    2144           5 :               (cli_setpid(cli1, 2),
    2145           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
    2146           5 :         EXPECTED(ret, False);
    2147           5 :         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
    2148             : 
    2149           5 :         ret = (cli_setpid(cli1, 1),
    2150          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
    2151           5 :               (cli_setpid(cli1, 2),
    2152           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
    2153           5 :         EXPECTED(ret, True);
    2154           5 :         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
    2155             : 
    2156          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
    2157           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
    2158           5 :         EXPECTED(ret, True);
    2159           5 :         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
    2160             : 
    2161          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
    2162           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
    2163           5 :         EXPECTED(ret, False);
    2164           5 :         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
    2165             : 
    2166          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
    2167           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
    2168           5 :         EXPECTED(ret, False);
    2169           5 :         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
    2170             : 
    2171          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
    2172           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
    2173           5 :         EXPECTED(ret, True);
    2174           5 :         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2175             : 
    2176           5 :         ret = (cli_setpid(cli1, 1),
    2177          10 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
    2178           5 :              (cli_setpid(cli1, 2),
    2179           5 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
    2180           5 :         EXPECTED(ret, False);
    2181           5 :         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2182             : 
    2183           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
    2184          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
    2185           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
    2186           5 :         EXPECTED(ret, False);
    2187           5 :         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
    2188             : 
    2189             : 
    2190          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
    2191           5 :               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
    2192           5 :         EXPECTED(ret, False);
    2193           5 :         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
    2194             : 
    2195           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2196           5 :         ret = NT_STATUS_IS_OK(status);
    2197           5 :         if (ret) {
    2198           5 :                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
    2199             :                                       NULL);
    2200           5 :                 ret = NT_STATUS_IS_OK(status);
    2201             :         }
    2202           5 :         EXPECTED(ret, False);
    2203           5 :         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
    2204             : 
    2205             : 
    2206           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2207           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2208          15 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
    2209           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
    2210           5 :         EXPECTED(ret, True);
    2211           5 :         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
    2212             : 
    2213             : 
    2214           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
    2215           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
    2216          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
    2217           5 :               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
    2218           5 :               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2219          10 :                                              150, 4, NULL))) &&
    2220           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
    2221           5 :         EXPECTED(ret, True);
    2222           5 :         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
    2223             : 
    2224           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
    2225           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
    2226           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2227          10 :                                            160, 4, NULL)) &&
    2228           5 :               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
    2229           5 :         EXPECTED(ret, True);
    2230           5 :         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
    2231             : 
    2232           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
    2233           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
    2234           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2235          10 :                                            170, 4, NULL)) &&
    2236           5 :               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
    2237           5 :         EXPECTED(ret, True);
    2238           5 :         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
    2239             : 
    2240           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
    2241           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
    2242           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
    2243           5 :               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2244          10 :                                             190, 4, NULL)) &&
    2245           5 :               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
    2246           5 :         EXPECTED(ret, True);
    2247           5 :         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
    2248             : 
    2249           5 :         cli_close(cli1, fnum1);
    2250           5 :         cli_close(cli2, fnum2);
    2251           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2252           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
    2253           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2254           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
    2255           5 :               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
    2256          15 :               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
    2257           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
    2258           5 :         cli_close(cli1, f);
    2259           5 :         cli_close(cli1, fnum1);
    2260           5 :         EXPECTED(ret, True);
    2261           5 :         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
    2262             : 
    2263           5 :  fail:
    2264           5 :         cli_close(cli1, fnum1);
    2265           5 :         cli_close(cli2, fnum2);
    2266           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2267           5 :         torture_close_connection(cli1);
    2268           5 :         torture_close_connection(cli2);
    2269             : 
    2270           5 :         printf("finished locktest4\n");
    2271           5 :         return correct;
    2272             : }
    2273             : 
    2274             : /*
    2275             :   looks at lock upgrade/downgrade.
    2276             : */
    2277           5 : static bool run_locktest5(int dummy)
    2278             : {
    2279           0 :         static struct cli_state *cli1, *cli2;
    2280           5 :         const char *fname = "\\lockt5.lck";
    2281           0 :         uint16_t fnum1, fnum2, fnum3;
    2282           0 :         bool ret;
    2283           0 :         char buf[1000];
    2284           5 :         bool correct = True;
    2285           0 :         NTSTATUS status;
    2286             : 
    2287           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2288           0 :                 return False;
    2289             :         }
    2290             : 
    2291           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2292           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2293             : 
    2294           5 :         printf("starting locktest5\n");
    2295             : 
    2296           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2297             : 
    2298           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2299           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2300           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
    2301             : 
    2302           5 :         memset(buf, 0, sizeof(buf));
    2303             : 
    2304           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2305             :                               NULL);
    2306           5 :         if (!NT_STATUS_IS_OK(status)) {
    2307           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2308           0 :                 correct = False;
    2309           0 :                 goto fail;
    2310             :         }
    2311             : 
    2312             :         /* Check for NT bug... */
    2313          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2314           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
    2315           5 :         cli_close(cli1, fnum1);
    2316           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2317           5 :         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
    2318           5 :         ret = NT_STATUS_IS_OK(status);
    2319           5 :         EXPECTED(ret, True);
    2320           5 :         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
    2321           5 :         cli_close(cli1, fnum1);
    2322           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2323           5 :         cli_unlock(cli1, fnum3, 0, 1);
    2324             : 
    2325          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2326           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
    2327           5 :         EXPECTED(ret, True);
    2328           5 :         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
    2329             : 
    2330           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
    2331           5 :         ret = NT_STATUS_IS_OK(status);
    2332           5 :         EXPECTED(ret, False);
    2333             : 
    2334           5 :         printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
    2335             : 
    2336             :         /* Unlock the process 2 lock. */
    2337           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2338             : 
    2339           5 :         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
    2340           5 :         ret = NT_STATUS_IS_OK(status);
    2341           5 :         EXPECTED(ret, False);
    2342             : 
    2343           5 :         printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
    2344             : 
    2345             :         /* Unlock the process 1 fnum3 lock. */
    2346           5 :         cli_unlock(cli1, fnum3, 0, 4);
    2347             : 
    2348             :         /* Stack 2 more locks here. */
    2349          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
    2350           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
    2351             : 
    2352           5 :         EXPECTED(ret, True);
    2353           5 :         printf("the same process %s stack read locks\n", ret?"can":"cannot");
    2354             : 
    2355             :         /* Unlock the first process lock, then check this was the WRITE lock that was
    2356             :                 removed. */
    2357             : 
    2358          10 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2359           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
    2360             : 
    2361           5 :         EXPECTED(ret, True);
    2362           5 :         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
    2363             : 
    2364             :         /* Unlock the process 2 lock. */
    2365           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2366             : 
    2367             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
    2368             : 
    2369           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
    2370          10 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2371           5 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2372             : 
    2373           5 :         EXPECTED(ret, True);
    2374           5 :         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
    2375             : 
    2376             :         /* Ensure the next unlock fails. */
    2377           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2378           5 :         EXPECTED(ret, False);
    2379           5 :         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
    2380             : 
    2381             :         /* Ensure connection 2 can get a write lock. */
    2382           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
    2383           5 :         ret = NT_STATUS_IS_OK(status);
    2384           5 :         EXPECTED(ret, True);
    2385             : 
    2386           5 :         printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
    2387             : 
    2388             : 
    2389           5 :  fail:
    2390           5 :         cli_close(cli1, fnum1);
    2391           5 :         cli_close(cli2, fnum2);
    2392           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2393           5 :         if (!torture_close_connection(cli1)) {
    2394           0 :                 correct = False;
    2395             :         }
    2396           5 :         if (!torture_close_connection(cli2)) {
    2397           0 :                 correct = False;
    2398             :         }
    2399             : 
    2400           5 :         printf("finished locktest5\n");
    2401             : 
    2402           5 :         return correct;
    2403             : }
    2404             : 
    2405             : /*
    2406             :   tries the unusual lockingX locktype bits
    2407             : */
    2408           5 : static bool run_locktest6(int dummy)
    2409             : {
    2410           0 :         static struct cli_state *cli;
    2411           5 :         const char *fname[1] = { "\\lock6.txt" };
    2412           0 :         int i;
    2413           0 :         uint16_t fnum;
    2414           0 :         NTSTATUS status;
    2415             : 
    2416           5 :         if (!torture_open_connection(&cli, 0)) {
    2417           0 :                 return False;
    2418             :         }
    2419             : 
    2420           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    2421             : 
    2422           5 :         printf("starting locktest6\n");
    2423             : 
    2424          10 :         for (i=0;i<1;i++) {
    2425           5 :                 printf("Testing %s\n", fname[i]);
    2426             : 
    2427           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2428             : 
    2429           5 :                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    2430           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
    2431           5 :                 cli_close(cli, fnum);
    2432           5 :                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
    2433             : 
    2434           5 :                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
    2435           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
    2436           5 :                 cli_close(cli, fnum);
    2437           5 :                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
    2438             : 
    2439           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2440             :         }
    2441             : 
    2442           5 :         torture_close_connection(cli);
    2443             : 
    2444           5 :         printf("finished locktest6\n");
    2445           5 :         return True;
    2446             : }
    2447             : 
    2448           5 : static bool run_locktest7(int dummy)
    2449             : {
    2450           0 :         struct cli_state *cli1;
    2451           5 :         const char *fname = "\\lockt7.lck";
    2452           0 :         uint16_t fnum1;
    2453           0 :         char buf[200];
    2454           5 :         bool correct = False;
    2455           0 :         size_t nread;
    2456           0 :         NTSTATUS status;
    2457             : 
    2458           5 :         if (!torture_open_connection(&cli1, 0)) {
    2459           0 :                 return False;
    2460             :         }
    2461             : 
    2462           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2463             : 
    2464           5 :         printf("starting locktest7\n");
    2465             : 
    2466           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2467             : 
    2468           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2469             : 
    2470           5 :         memset(buf, 0, sizeof(buf));
    2471             : 
    2472           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2473             :                               NULL);
    2474           5 :         if (!NT_STATUS_IS_OK(status)) {
    2475           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2476           0 :                 goto fail;
    2477             :         }
    2478             : 
    2479           5 :         cli_setpid(cli1, 1);
    2480             : 
    2481           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2482           5 :         if (!NT_STATUS_IS_OK(status)) {
    2483           0 :                 printf("Unable to apply read lock on range 130:4, "
    2484             :                        "error was %s\n", nt_errstr(status));
    2485           0 :                 goto fail;
    2486             :         } else {
    2487           5 :                 printf("pid1 successfully locked range 130:4 for READ\n");
    2488             :         }
    2489             : 
    2490           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2491           5 :         if (!NT_STATUS_IS_OK(status)) {
    2492           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2493             :                       nt_errstr(status));
    2494           0 :                 goto fail;
    2495           5 :         } else if (nread != 4) {
    2496           0 :                 printf("pid1 unable to read the range 130:4, "
    2497             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2498           0 :                 goto fail;
    2499             :         } else {
    2500           5 :                 printf("pid1 successfully read the range 130:4\n");
    2501             :         }
    2502             : 
    2503           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2504           5 :         if (!NT_STATUS_IS_OK(status)) {
    2505           5 :                 printf("pid1 unable to write to the range 130:4, error was "
    2506             :                        "%s\n", nt_errstr(status));
    2507           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2508           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2509           0 :                         goto fail;
    2510             :                 }
    2511             :         } else {
    2512           0 :                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
    2513           0 :                 goto fail;
    2514             :         }
    2515             : 
    2516           5 :         cli_setpid(cli1, 2);
    2517             : 
    2518           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2519           5 :         if (!NT_STATUS_IS_OK(status)) {
    2520           0 :                 printf("pid2 unable to read the range 130:4, error was %s\n",
    2521             :                       nt_errstr(status));
    2522           0 :                 goto fail;
    2523           5 :         } else if (nread != 4) {
    2524           0 :                 printf("pid2 unable to read the range 130:4, "
    2525             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2526           0 :                 goto fail;
    2527             :         } else {
    2528           5 :                 printf("pid2 successfully read the range 130:4\n");
    2529             :         }
    2530             : 
    2531           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2532           5 :         if (!NT_STATUS_IS_OK(status)) {
    2533           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2534             :                        "%s\n", nt_errstr(status));
    2535           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2536           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2537           0 :                         goto fail;
    2538             :                 }
    2539             :         } else {
    2540           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2541           0 :                 goto fail;
    2542             :         }
    2543             : 
    2544           5 :         cli_setpid(cli1, 1);
    2545           5 :         cli_unlock(cli1, fnum1, 130, 4);
    2546             : 
    2547           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
    2548           5 :         if (!NT_STATUS_IS_OK(status)) {
    2549           0 :                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
    2550           0 :                 goto fail;
    2551             :         } else {
    2552           5 :                 printf("pid1 successfully locked range 130:4 for WRITE\n");
    2553             :         }
    2554             : 
    2555           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2556           5 :         if (!NT_STATUS_IS_OK(status)) {
    2557           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2558             :                       nt_errstr(status));
    2559           0 :                 goto fail;
    2560           5 :         } else if (nread != 4) {
    2561           0 :                 printf("pid1 unable to read the range 130:4, "
    2562             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2563           0 :                 goto fail;
    2564             :         } else {
    2565           5 :                 printf("pid1 successfully read the range 130:4\n");
    2566             :         }
    2567             : 
    2568           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2569           5 :         if (!NT_STATUS_IS_OK(status)) {
    2570           0 :                 printf("pid1 unable to write to the range 130:4, error was "
    2571             :                        "%s\n", nt_errstr(status));
    2572           0 :                 goto fail;
    2573             :         } else {
    2574           5 :                 printf("pid1 successfully wrote to the range 130:4\n");
    2575             :         }
    2576             : 
    2577           5 :         cli_setpid(cli1, 2);
    2578             : 
    2579           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2580           5 :         if (!NT_STATUS_IS_OK(status)) {
    2581           5 :                 printf("pid2 unable to read the range 130:4, error was "
    2582             :                        "%s\n", nt_errstr(status));
    2583           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2584           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2585           0 :                         goto fail;
    2586             :                 }
    2587             :         } else {
    2588           0 :                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
    2589             :                        (unsigned long)nread);
    2590           0 :                 goto fail;
    2591             :         }
    2592             : 
    2593           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2594           5 :         if (!NT_STATUS_IS_OK(status)) {
    2595           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2596             :                        "%s\n", nt_errstr(status));
    2597           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2598           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2599           0 :                         goto fail;
    2600             :                 }
    2601             :         } else {
    2602           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2603           0 :                 goto fail;
    2604             :         }
    2605             : 
    2606           5 :         cli_unlock(cli1, fnum1, 130, 0);
    2607           5 :         correct = True;
    2608             : 
    2609           5 : fail:
    2610           5 :         cli_close(cli1, fnum1);
    2611           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2612           5 :         torture_close_connection(cli1);
    2613             : 
    2614           5 :         printf("finished locktest7\n");
    2615           5 :         return correct;
    2616             : }
    2617             : 
    2618             : /*
    2619             :  * This demonstrates a problem with our use of GPFS share modes: A file
    2620             :  * descriptor sitting in the pending close queue holding a GPFS share mode
    2621             :  * blocks opening a file another time. Happens with Word 2007 temp files.
    2622             :  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
    2623             :  * open is denied with NT_STATUS_SHARING_VIOLATION.
    2624             :  */
    2625             : 
    2626           0 : static bool run_locktest8(int dummy)
    2627             : {
    2628           0 :         struct cli_state *cli1;
    2629           0 :         const char *fname = "\\lockt8.lck";
    2630           0 :         uint16_t fnum1, fnum2;
    2631           0 :         char buf[200];
    2632           0 :         bool correct = False;
    2633           0 :         NTSTATUS status;
    2634             : 
    2635           0 :         if (!torture_open_connection(&cli1, 0)) {
    2636           0 :                 return False;
    2637             :         }
    2638             : 
    2639           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2640             : 
    2641           0 :         printf("starting locktest8\n");
    2642             : 
    2643           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2644             : 
    2645           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
    2646             :                           &fnum1);
    2647           0 :         if (!NT_STATUS_IS_OK(status)) {
    2648           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2649           0 :                 return false;
    2650             :         }
    2651             : 
    2652           0 :         memset(buf, 0, sizeof(buf));
    2653             : 
    2654           0 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
    2655           0 :         if (!NT_STATUS_IS_OK(status)) {
    2656           0 :                 d_fprintf(stderr, "cli_openx second time returned %s\n",
    2657             :                           nt_errstr(status));
    2658           0 :                 goto fail;
    2659             :         }
    2660             : 
    2661           0 :         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
    2662           0 :         if (!NT_STATUS_IS_OK(status)) {
    2663           0 :                 printf("Unable to apply read lock on range 1:1, error was "
    2664             :                        "%s\n", nt_errstr(status));
    2665           0 :                 goto fail;
    2666             :         }
    2667             : 
    2668           0 :         status = cli_close(cli1, fnum1);
    2669           0 :         if (!NT_STATUS_IS_OK(status)) {
    2670           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2671           0 :                 goto fail;
    2672             :         }
    2673             : 
    2674           0 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2675           0 :         if (!NT_STATUS_IS_OK(status)) {
    2676           0 :                 d_fprintf(stderr, "cli_openx third time returned %s\n",
    2677             :                           nt_errstr(status));
    2678           0 :                 goto fail;
    2679             :         }
    2680             : 
    2681           0 :         correct = true;
    2682             : 
    2683           0 : fail:
    2684           0 :         cli_close(cli1, fnum1);
    2685           0 :         cli_close(cli1, fnum2);
    2686           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2687           0 :         torture_close_connection(cli1);
    2688             : 
    2689           0 :         printf("finished locktest8\n");
    2690           0 :         return correct;
    2691             : }
    2692             : 
    2693             : /*
    2694             :  * This test is designed to be run in conjunction with
    2695             :  * external NFS or POSIX locks taken in the filesystem.
    2696             :  * It checks that the smbd server will block until the
    2697             :  * lock is released and then acquire it. JRA.
    2698             :  */
    2699             : 
    2700             : static bool got_alarm;
    2701             : static struct cli_state *alarm_cli;
    2702             : 
    2703           0 : static void alarm_handler(int dummy)
    2704             : {
    2705           0 :         got_alarm = True;
    2706           0 : }
    2707             : 
    2708           0 : static void alarm_handler_parent(int dummy)
    2709             : {
    2710           0 :         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    2711           0 : }
    2712             : 
    2713           8 : static void do_local_lock(const char *fname, int read_fd, int write_fd)
    2714             : {
    2715           0 :         int fd;
    2716           8 :         char c = '\0';
    2717           0 :         struct flock lock;
    2718           8 :         const char *local_pathname = NULL;
    2719           0 :         int ret;
    2720             : 
    2721           8 :         local_pathname = talloc_asprintf(talloc_tos(),
    2722             :                         "%s/%s", local_path, fname);
    2723           8 :         if (!local_pathname) {
    2724           0 :                 printf("child: alloc fail\n");
    2725           0 :                 exit(1);
    2726             :         }
    2727             : 
    2728           8 :         unlink(local_pathname);
    2729           8 :         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
    2730           8 :         if (fd == -1) {
    2731           0 :                 printf("child: open of %s failed %s.\n",
    2732           0 :                         local_pathname, strerror(errno));
    2733           0 :                 exit(1);
    2734             :         }
    2735             : 
    2736             :         /* Now take a fcntl lock. */
    2737           8 :         lock.l_type = F_WRLCK;
    2738           8 :         lock.l_whence = SEEK_SET;
    2739           8 :         lock.l_start = 0;
    2740           8 :         lock.l_len = 4;
    2741           8 :         lock.l_pid = getpid();
    2742             : 
    2743           8 :         ret = fcntl(fd,F_SETLK,&lock);
    2744           8 :         if (ret == -1) {
    2745           0 :                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
    2746           0 :                         local_pathname, strerror(errno));
    2747           0 :                 exit(1);
    2748             :         } else {
    2749           8 :                 printf("child: got lock 0:4 on file %s.\n",
    2750             :                         local_pathname );
    2751           8 :                 fflush(stdout);
    2752             :         }
    2753             : 
    2754           8 :         CatchSignal(SIGALRM, alarm_handler);
    2755           8 :         alarm(5);
    2756             :         /* Signal the parent. */
    2757           8 :         if (write(write_fd, &c, 1) != 1) {
    2758           0 :                 printf("child: start signal fail %s.\n",
    2759           0 :                         strerror(errno));
    2760           0 :                 exit(1);
    2761             :         }
    2762           8 :         alarm(0);
    2763             : 
    2764           8 :         alarm(10);
    2765             :         /* Wait for the parent to be ready. */
    2766           8 :         if (read(read_fd, &c, 1) != 1) {
    2767           0 :                 printf("child: reply signal fail %s.\n",
    2768           0 :                         strerror(errno));
    2769           0 :                 exit(1);
    2770             :         }
    2771           8 :         alarm(0);
    2772             : 
    2773           8 :         sleep(5);
    2774           8 :         close(fd);
    2775           8 :         printf("child: released lock 0:4 on file %s.\n",
    2776             :                 local_pathname );
    2777           8 :         fflush(stdout);
    2778           8 :         exit(0);
    2779             : }
    2780             : 
    2781           8 : static bool _run_locktest9X(const char *fname, int timeout)
    2782             : {
    2783           0 :         struct cli_state *cli1;
    2784           8 :         char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname);
    2785           0 :         uint16_t fnum;
    2786           8 :         bool correct = False;
    2787           0 :         int pipe_in[2], pipe_out[2];
    2788           0 :         pid_t child_pid;
    2789           8 :         char c = '\0';
    2790           0 :         int ret;
    2791           0 :         struct timeval start;
    2792           0 :         double seconds;
    2793           0 :         NTSTATUS status;
    2794             : 
    2795           8 :         printf("starting locktest9X: %s\n", fname);
    2796             : 
    2797           8 :         if (local_path == NULL) {
    2798           0 :                 d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n");
    2799           0 :                 return false;
    2800             :         }
    2801             : 
    2802           8 :         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
    2803           0 :                 return false;
    2804             :         }
    2805             : 
    2806           8 :         child_pid = fork();
    2807          16 :         if (child_pid == -1) {
    2808           0 :                 return false;
    2809             :         }
    2810             : 
    2811          16 :         if (child_pid == 0) {
    2812             :                 /* Child. */
    2813           8 :                 do_local_lock(fname, pipe_out[0], pipe_in[1]);
    2814           0 :                 exit(0);
    2815             :         }
    2816             : 
    2817           8 :         close(pipe_out[0]);
    2818           8 :         close(pipe_in[1]);
    2819           8 :         pipe_out[0] = -1;
    2820           8 :         pipe_in[1] = -1;
    2821             : 
    2822             :         /* Parent. */
    2823           8 :         ret = read(pipe_in[0], &c, 1);
    2824           8 :         if (ret != 1) {
    2825           0 :                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
    2826           0 :                         strerror(errno));
    2827           0 :                 return false;
    2828             :         }
    2829             : 
    2830           8 :         if (!torture_open_connection(&cli1, 0)) {
    2831           0 :                 return false;
    2832             :         }
    2833             : 
    2834           8 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2835             : 
    2836           8 :         status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE,
    2837             :                           &fnum);
    2838           8 :         if (!NT_STATUS_IS_OK(status)) {
    2839           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2840           0 :                 return false;
    2841             :         }
    2842             : 
    2843             :         /* Ensure the child has the lock. */
    2844           8 :         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
    2845           8 :         if (NT_STATUS_IS_OK(status)) {
    2846           0 :                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
    2847           0 :                 goto fail;
    2848             :         } else {
    2849           8 :                 d_printf("Child has the lock.\n");
    2850             :         }
    2851             : 
    2852             :         /* Tell the child to wait 5 seconds then exit. */
    2853           8 :         ret = write(pipe_out[1], &c, 1);
    2854           8 :         if (ret != 1) {
    2855           0 :                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
    2856           0 :                         strerror(errno));
    2857           0 :                 goto fail;
    2858             :         }
    2859             : 
    2860             :         /* Wait 20 seconds for the lock. */
    2861           8 :         alarm_cli = cli1;
    2862           8 :         CatchSignal(SIGALRM, alarm_handler_parent);
    2863           8 :         alarm(20);
    2864             : 
    2865           8 :         start = timeval_current();
    2866             : 
    2867           8 :         status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK);
    2868           8 :         if (!NT_STATUS_IS_OK(status)) {
    2869           0 :                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
    2870             :                        "%s\n", nt_errstr(status));
    2871           0 :                 goto fail_nofd;
    2872             :         }
    2873           8 :         alarm(0);
    2874             : 
    2875           8 :         seconds = timeval_elapsed(&start);
    2876             : 
    2877           8 :         printf("Parent got the lock after %.2f seconds.\n",
    2878             :                 seconds);
    2879             : 
    2880           8 :         status = cli_close(cli1, fnum);
    2881           8 :         if (!NT_STATUS_IS_OK(status)) {
    2882           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2883           0 :                 goto fail;
    2884             :         }
    2885             : 
    2886           8 :         correct = true;
    2887             : 
    2888           8 : fail:
    2889           8 :         cli_close(cli1, fnum);
    2890           8 :         torture_close_connection(cli1);
    2891             : 
    2892           8 : fail_nofd:
    2893             : 
    2894           8 :         printf("finished locktest9X: %s\n", fname);
    2895           8 :         return correct;
    2896             : }
    2897             : 
    2898           4 : static bool run_locktest9a(int dummy)
    2899             : {
    2900           4 :         return _run_locktest9X("lock9a.dat", -1);
    2901             : }
    2902             : 
    2903           4 : static bool run_locktest9b(int dummy)
    2904             : {
    2905           4 :         return _run_locktest9X("lock9b.dat", 10000);
    2906             : }
    2907             : 
    2908             : struct locktest10_state {
    2909             :         bool ok;
    2910             :         bool done;
    2911             : };
    2912             : 
    2913             : static void locktest10_lockingx_done(struct tevent_req *subreq);
    2914             : static void locktest10_read_andx_done(struct tevent_req *subreq);
    2915             : 
    2916           5 : static bool run_locktest10(int dummy)
    2917             : {
    2918           5 :         struct tevent_context *ev = NULL;
    2919           5 :         struct cli_state *cli1 = NULL;
    2920           5 :         struct cli_state *cli2 = NULL;
    2921           5 :         struct smb1_lock_element lck = { 0 };
    2922           5 :         struct tevent_req *reqs[2] = { NULL };
    2923           5 :         struct tevent_req *smbreqs[2] = { NULL };
    2924           5 :         const char fname[] = "\\lockt10.lck";
    2925           0 :         uint16_t fnum1, fnum2;
    2926           5 :         bool ret = false;
    2927           0 :         bool ok;
    2928           5 :         uint8_t data = 1;
    2929           5 :         struct locktest10_state state = { .ok = true };
    2930           0 :         NTSTATUS status;
    2931             : 
    2932           5 :         printf("starting locktest10\n");
    2933             : 
    2934           5 :         ev = samba_tevent_context_init(NULL);
    2935           5 :         if (ev == NULL) {
    2936           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    2937           0 :                 goto done;
    2938             :         }
    2939             : 
    2940           5 :         ok = torture_open_connection(&cli1, 0);
    2941           5 :         if (!ok) {
    2942           0 :                 goto done;
    2943             :         }
    2944           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2945             : 
    2946           5 :         ok = torture_open_connection(&cli2, 1);
    2947           5 :         if (!ok) {
    2948           0 :                 goto done;
    2949             :         }
    2950           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2951             : 
    2952           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    2953           5 :         if (!NT_STATUS_IS_OK(status)) {
    2954           0 :                 d_fprintf(stderr,
    2955             :                           "cli_openx failed: %s\n",
    2956             :                           nt_errstr(status));
    2957           0 :                 goto done;
    2958             :         }
    2959             : 
    2960           5 :         status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
    2961           5 :         if (!NT_STATUS_IS_OK(status)) {
    2962           0 :                 d_fprintf(stderr,
    2963             :                           "cli_writeall failed: %s\n",
    2964             :                           nt_errstr(status));
    2965           0 :                 goto done;
    2966             :         }
    2967             : 
    2968           5 :         status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    2969           5 :         if (!NT_STATUS_IS_OK(status)) {
    2970           0 :                 d_fprintf(stderr,
    2971             :                           "cli_openx failed: %s\n",
    2972             :                           nt_errstr(status));
    2973           0 :                 goto done;
    2974             :         }
    2975             : 
    2976           5 :         status = cli_locktype(
    2977             :                 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    2978           5 :         if (!NT_STATUS_IS_OK(status)) {
    2979           0 :                 d_fprintf(stderr,
    2980             :                           "cli_locktype failed: %s\n",
    2981             :                           nt_errstr(status));
    2982           0 :                 goto done;
    2983             :         }
    2984             : 
    2985           5 :         lck = (struct smb1_lock_element) {
    2986           5 :                 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
    2987             :         };
    2988             : 
    2989           5 :         reqs[0] = cli_lockingx_create(
    2990             :                 ev,                             /* mem_ctx */
    2991             :                 ev,                             /* tevent_context */
    2992             :                 cli1,                           /* cli */
    2993             :                 fnum1,                          /* fnum */
    2994             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    2995             :                 0,                              /* newoplocklevel */
    2996             :                 1,                              /* timeout */
    2997             :                 0,                              /* num_unlocks */
    2998             :                 NULL,                           /* unlocks */
    2999             :                 1,                              /* num_locks */
    3000             :                 &lck,                               /* locks */
    3001             :                 &smbreqs[0]);                       /* psmbreq */
    3002           5 :         if (reqs[0] == NULL) {
    3003           0 :                 d_fprintf(stderr, "cli_lockingx_create failed\n");
    3004           0 :                 goto done;
    3005             :         }
    3006           5 :         tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
    3007             : 
    3008           5 :         reqs[1] = cli_read_andx_create(
    3009             :                 ev,             /* mem_ctx */
    3010             :                 ev,             /* ev */
    3011             :                 cli1,           /* cli */
    3012             :                 fnum1,          /* fnum */
    3013             :                 0,              /* offset */
    3014             :                 1,              /* size */
    3015             :                 &smbreqs[1]);       /* psmbreq */
    3016           5 :         if (reqs[1] == NULL) {
    3017           0 :                 d_fprintf(stderr, "cli_read_andx_create failed\n");
    3018           0 :                 goto done;
    3019             :         }
    3020           5 :         tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
    3021             : 
    3022           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
    3023           5 :         if (!NT_STATUS_IS_OK(status)) {
    3024           0 :                 d_fprintf(stderr,
    3025             :                           "smb1cli_req_chain_submit failed: %s\n",
    3026             :                           nt_errstr(status));
    3027           0 :                 goto done;
    3028             :         }
    3029             : 
    3030          30 :         while (!state.done) {
    3031          25 :                 tevent_loop_once(ev);
    3032             :         }
    3033             : 
    3034           5 :         torture_close_connection(cli1);
    3035             : 
    3036           5 :         if (state.ok) {
    3037           5 :                 ret = true;
    3038             :         }
    3039           0 : done:
    3040           5 :         return ret;
    3041             : }
    3042             : 
    3043           5 : static void locktest10_lockingx_done(struct tevent_req *subreq)
    3044             : {
    3045           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3046           0 :         NTSTATUS status;
    3047             : 
    3048           5 :         status = cli_lockingx_recv(subreq);
    3049           5 :         TALLOC_FREE(subreq);
    3050             : 
    3051           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3052           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3053           0 :                 state->ok = false;
    3054             :         }
    3055           5 : }
    3056             : 
    3057           5 : static void locktest10_read_andx_done(struct tevent_req *subreq)
    3058             : {
    3059           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3060           5 :         ssize_t received = -1;
    3061           5 :         uint8_t *rcvbuf = NULL;
    3062           0 :         NTSTATUS status;
    3063             : 
    3064           5 :         status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3065             : 
    3066           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
    3067           0 :                 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
    3068           0 :                 state->ok = false;
    3069             :         }
    3070             : 
    3071           5 :         state->done = true;
    3072           5 :         TALLOC_FREE(subreq);
    3073           5 : }
    3074             : 
    3075           5 : static bool run_locktest11(int dummy)
    3076             : {
    3077           0 :         struct cli_state *cli1;
    3078           5 :         const char *fname = "\\lockt11.lck";
    3079           0 :         NTSTATUS status;
    3080           0 :         uint16_t fnum;
    3081           5 :         bool ret = false;
    3082             : 
    3083           5 :         if (!torture_open_connection(&cli1, 0)) {
    3084           0 :                 return false;
    3085             :         }
    3086             : 
    3087           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3088             : 
    3089           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3090             : 
    3091           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
    3092           5 :         if (!NT_STATUS_IS_OK(status)) {
    3093           0 :                 d_fprintf(stderr,
    3094             :                           "cli_openx returned %s\n",
    3095             :                           nt_errstr(status));
    3096           0 :                 return false;
    3097             :         }
    3098             : 
    3099             :         /*
    3100             :          * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
    3101             :          * returns NT_STATUS_OK
    3102             :          */
    3103             : 
    3104           5 :         status = cli_lockingx(
    3105             :                 cli1,                           /* cli */
    3106             :                 fnum,                           /* fnum */
    3107             :                 LOCKING_ANDX_CANCEL_LOCK,       /* typeoflock */
    3108             :                 0,                              /* newoplocklevel */
    3109             :                 0,                              /* timeout */
    3110             :                 0,                              /* num_unlocks */
    3111             :                 NULL,                           /* unlocks */
    3112             :                 0,                              /* num_locks */
    3113             :                 NULL);                          /* locks */
    3114             : 
    3115           5 :         if (!NT_STATUS_IS_OK(status)) {
    3116           1 :                 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
    3117           1 :                 goto fail;
    3118             :         }
    3119             : 
    3120           4 :         ret = true;
    3121           5 : fail:
    3122           5 :         cli_close(cli1, fnum);
    3123           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3124             : 
    3125           5 :         return ret;
    3126             : }
    3127             : 
    3128             : struct deferred_close_state {
    3129             :         struct tevent_context *ev;
    3130             :         struct cli_state *cli;
    3131             :         uint16_t fnum;
    3132             : };
    3133             : 
    3134             : static void deferred_close_waited(struct tevent_req *subreq);
    3135             : static void deferred_close_done(struct tevent_req *subreq);
    3136             : 
    3137           5 : static struct tevent_req *deferred_close_send(
    3138             :         TALLOC_CTX *mem_ctx,
    3139             :         struct tevent_context *ev,
    3140             :         int wait_secs,
    3141             :         struct cli_state *cli,
    3142             :         uint16_t fnum)
    3143             : {
    3144           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3145           5 :         struct deferred_close_state *state = NULL;
    3146           5 :         struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
    3147             : 
    3148           5 :         req = tevent_req_create(
    3149             :                 mem_ctx, &state, struct deferred_close_state);
    3150           5 :         if (req == NULL) {
    3151           0 :                 return NULL;
    3152             :         }
    3153           5 :         state->ev = ev;
    3154           5 :         state->cli = cli;
    3155           5 :         state->fnum = fnum;
    3156             : 
    3157           5 :         subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
    3158           5 :         if (tevent_req_nomem(subreq, req)) {
    3159           0 :                 return tevent_req_post(req, ev);
    3160             :         }
    3161           5 :         tevent_req_set_callback(subreq, deferred_close_waited, req);
    3162           5 :         return req;
    3163             : }
    3164             : 
    3165           5 : static void deferred_close_waited(struct tevent_req *subreq)
    3166             : {
    3167           5 :         struct tevent_req *req = tevent_req_callback_data(
    3168             :                 subreq, struct tevent_req);
    3169           5 :         struct deferred_close_state *state = tevent_req_data(
    3170             :                 req, struct deferred_close_state);
    3171           0 :         bool ok;
    3172             : 
    3173           5 :         ok = tevent_wakeup_recv(subreq);
    3174           5 :         TALLOC_FREE(subreq);
    3175           5 :         if (!ok) {
    3176           0 :                 tevent_req_oom(req);
    3177           0 :                 return;
    3178             :         }
    3179             : 
    3180           5 :         subreq = cli_close_send(state, state->ev, state->cli, state->fnum, 0);
    3181           5 :         if (tevent_req_nomem(subreq, req)) {
    3182           0 :                 return;
    3183             :         }
    3184           5 :         tevent_req_set_callback(subreq, deferred_close_done, req);
    3185             : }
    3186             : 
    3187           5 : static void deferred_close_done(struct tevent_req *subreq)
    3188             : {
    3189           5 :         NTSTATUS status = cli_close_recv(subreq);
    3190           5 :         tevent_req_simple_finish_ntstatus(subreq, status);
    3191           5 : }
    3192             : 
    3193           5 : static NTSTATUS deferred_close_recv(struct tevent_req *req)
    3194             : {
    3195           5 :         return tevent_req_simple_recv_ntstatus(req);
    3196             : }
    3197             : 
    3198             : struct lockread_state {
    3199             :         struct smb1_lock_element lck;
    3200             :         struct tevent_req *reqs[2];
    3201             :         struct tevent_req *smbreqs[2];
    3202             :         NTSTATUS lock_status;
    3203             :         NTSTATUS read_status;
    3204             :         uint8_t *readbuf;
    3205             : };
    3206             : 
    3207             : static void lockread_lockingx_done(struct tevent_req *subreq);
    3208             : static void lockread_read_andx_done(struct tevent_req *subreq);
    3209             : 
    3210           5 : static struct tevent_req *lockread_send(
    3211             :         TALLOC_CTX *mem_ctx,
    3212             :         struct tevent_context *ev,
    3213             :         struct cli_state *cli,
    3214             :         uint16_t fnum)
    3215             : {
    3216           5 :         struct tevent_req *req = NULL;
    3217           5 :         struct lockread_state *state = NULL;
    3218           0 :         NTSTATUS status;
    3219             : 
    3220           5 :         req = tevent_req_create(mem_ctx, &state, struct lockread_state);
    3221           5 :         if (req == NULL) {
    3222           0 :                 return NULL;
    3223             :         }
    3224             : 
    3225          10 :         state->lck = (struct smb1_lock_element) {
    3226           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3227             :         };
    3228             : 
    3229          10 :         state->reqs[0] = cli_lockingx_create(
    3230             :                 ev,                             /* mem_ctx */
    3231             :                 ev,                             /* tevent_context */
    3232             :                 cli,                            /* cli */
    3233             :                 fnum,                           /* fnum */
    3234             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3235             :                 0,                              /* newoplocklevel */
    3236             :                 10000,                          /* timeout */
    3237             :                 0,                              /* num_unlocks */
    3238             :                 NULL,                           /* unlocks */
    3239             :                 1,                              /* num_locks */
    3240           5 :                 &state->lck,                     /* locks */
    3241           5 :                 &state->smbreqs[0]);             /* psmbreq */
    3242           5 :         if (tevent_req_nomem(state->reqs[0], req)) {
    3243           0 :                 return tevent_req_post(req, ev);
    3244             :         }
    3245           5 :         tevent_req_set_callback(
    3246             :                 state->reqs[0], lockread_lockingx_done, req);
    3247             : 
    3248          10 :         state->reqs[1] = cli_read_andx_create(
    3249             :                 ev,             /* mem_ctx */
    3250             :                 ev,             /* ev */
    3251             :                 cli,            /* cli */
    3252             :                 fnum,           /* fnum */
    3253             :                 0,              /* offset */
    3254             :                 1,              /* size */
    3255           5 :                 &state->smbreqs[1]);     /* psmbreq */
    3256           5 :         if (tevent_req_nomem(state->reqs[1], req)) {
    3257           0 :                 return tevent_req_post(req, ev);
    3258             :         }
    3259           5 :         tevent_req_set_callback(
    3260             :                 state->reqs[1], lockread_read_andx_done, req);
    3261             : 
    3262           5 :         status = smb1cli_req_chain_submit(state->smbreqs, 2);
    3263           5 :         if (tevent_req_nterror(req, status)) {
    3264           0 :                 return tevent_req_post(req, ev);
    3265             :         }
    3266           5 :         return req;
    3267             : }
    3268             : 
    3269           5 : static void lockread_lockingx_done(struct tevent_req *subreq)
    3270             : {
    3271           5 :         struct tevent_req *req = tevent_req_callback_data(
    3272             :                 subreq, struct tevent_req);
    3273           5 :         struct lockread_state *state = tevent_req_data(
    3274             :                 req, struct lockread_state);
    3275           5 :         state->lock_status = cli_lockingx_recv(subreq);
    3276           5 :         TALLOC_FREE(subreq);
    3277           5 :         d_fprintf(stderr,
    3278             :                   "lockingx returned %s\n",
    3279             :                   nt_errstr(state->lock_status));
    3280           5 : }
    3281             : 
    3282           5 : static void lockread_read_andx_done(struct tevent_req *subreq)
    3283             : {
    3284           5 :         struct tevent_req *req = tevent_req_callback_data(
    3285             :                 subreq, struct tevent_req);
    3286           5 :         struct lockread_state *state = tevent_req_data(
    3287             :                 req, struct lockread_state);
    3288           5 :         ssize_t received = -1;
    3289           5 :         uint8_t *rcvbuf = NULL;
    3290             : 
    3291           5 :         state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3292             : 
    3293           5 :         d_fprintf(stderr,
    3294             :                   "read returned %s\n",
    3295             :                   nt_errstr(state->read_status));
    3296             : 
    3297           5 :         if (!NT_STATUS_IS_OK(state->read_status)) {
    3298           4 :                 TALLOC_FREE(subreq);
    3299           4 :                 tevent_req_done(req);
    3300           4 :                 return;
    3301             :         }
    3302             : 
    3303           1 :         if (received > 0) {
    3304           1 :                 state->readbuf = talloc_memdup(state, rcvbuf, received);
    3305           1 :                 TALLOC_FREE(subreq);
    3306           1 :                 if (tevent_req_nomem(state->readbuf, req)) {
    3307           0 :                         return;
    3308             :                 }
    3309             :         }
    3310           1 :         TALLOC_FREE(subreq);
    3311           1 :         tevent_req_done(req);
    3312             : }
    3313             : 
    3314           5 : static NTSTATUS lockread_recv(
    3315             :         struct tevent_req *req,
    3316             :         NTSTATUS *lock_status,
    3317             :         NTSTATUS *read_status,
    3318             :         TALLOC_CTX *mem_ctx,
    3319             :         uint8_t **read_buf)
    3320             : {
    3321           5 :         struct lockread_state *state = tevent_req_data(
    3322             :                 req, struct lockread_state);
    3323           0 :         NTSTATUS status;
    3324             : 
    3325           5 :         if (tevent_req_is_nterror(req, &status)) {
    3326           0 :                 return status;
    3327             :         }
    3328             : 
    3329           5 :         *lock_status = state->lock_status;
    3330           5 :         *read_status = state->read_status;
    3331           5 :         if (state->readbuf != NULL) {
    3332           1 :                 *read_buf = talloc_move(mem_ctx, &state->readbuf);
    3333             :         } else {
    3334           4 :                 *read_buf = NULL;
    3335             :         }
    3336             : 
    3337           5 :         return NT_STATUS_OK;
    3338             : }
    3339             : 
    3340             : struct lock12_state {
    3341             :         uint8_t dummy;
    3342             : };
    3343             : 
    3344             : static void lock12_closed(struct tevent_req *subreq);
    3345             : static void lock12_read(struct tevent_req *subreq);
    3346             : 
    3347           5 : static struct tevent_req *lock12_send(
    3348             :         TALLOC_CTX *mem_ctx,
    3349             :         struct tevent_context *ev,
    3350             :         struct cli_state *cli,
    3351             :         uint16_t fnum1,
    3352             :         uint16_t fnum2)
    3353             : {
    3354           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3355           5 :         struct lock12_state *state = NULL;
    3356             : 
    3357           5 :         req = tevent_req_create(mem_ctx, &state, struct lock12_state);
    3358           5 :         if (req == NULL) {
    3359           0 :                 return NULL;
    3360             :         }
    3361             : 
    3362           5 :         subreq = deferred_close_send(state, ev, 1, cli, fnum1);
    3363           5 :         if (tevent_req_nomem(subreq, req)) {
    3364           0 :                 return tevent_req_post(req, ev);
    3365             :         }
    3366           5 :         tevent_req_set_callback(subreq, lock12_closed, req);
    3367             : 
    3368           5 :         subreq = lockread_send(state, ev, cli, fnum2);
    3369           5 :         if (tevent_req_nomem(subreq, req)) {
    3370           0 :                 return tevent_req_post(req, ev);
    3371             :         }
    3372           5 :         tevent_req_set_callback(subreq, lock12_read, req);
    3373             : 
    3374           5 :         return req;
    3375             : }
    3376             : 
    3377           5 : static void lock12_closed(struct tevent_req *subreq)
    3378             : {
    3379           5 :         struct tevent_req *req = tevent_req_callback_data(
    3380             :                 subreq, struct tevent_req);
    3381           0 :         NTSTATUS status;
    3382             : 
    3383           5 :         status = deferred_close_recv(subreq);
    3384           5 :         TALLOC_FREE(subreq);
    3385           5 :         DBG_DEBUG("close returned %s\n", nt_errstr(status));
    3386           5 :         if (tevent_req_nterror(req, status)) {
    3387           0 :                 return;
    3388             :         }
    3389             : }
    3390             : 
    3391           5 : static void lock12_read(struct tevent_req *subreq)
    3392             : {
    3393           5 :         struct tevent_req *req = tevent_req_callback_data(
    3394             :                 subreq, struct tevent_req);
    3395           5 :         struct lock12_state *state = tevent_req_data(
    3396             :                 req, struct lock12_state);
    3397           0 :         NTSTATUS status, lock_status, read_status;
    3398           5 :         uint8_t *buf = NULL;
    3399             : 
    3400           5 :         status = lockread_recv(
    3401             :                 subreq, &lock_status, &read_status, state, &buf);
    3402           5 :         TALLOC_FREE(subreq);
    3403          10 :         if (tevent_req_nterror(req, status) ||
    3404          10 :             tevent_req_nterror(req, lock_status) ||
    3405           5 :             tevent_req_nterror(req, read_status)) {
    3406           4 :                 return;
    3407             :         }
    3408           1 :         tevent_req_done(req);
    3409             : }
    3410             : 
    3411           5 : static NTSTATUS lock12_recv(struct tevent_req *req)
    3412             : 
    3413             : {
    3414           0 :         NTSTATUS status;
    3415             : 
    3416           5 :         if (tevent_req_is_nterror(req, &status)) {
    3417           4 :                 return status;
    3418             :         }
    3419           1 :         return NT_STATUS_OK;
    3420             : }
    3421             : 
    3422           5 : static bool run_locktest12(int dummy)
    3423             : {
    3424           5 :         struct tevent_context *ev = NULL;
    3425           5 :         struct tevent_req *req = NULL;
    3426           5 :         struct cli_state *cli = NULL;
    3427           5 :         const char fname[] = "\\lockt12.lck";
    3428           0 :         uint16_t fnum1, fnum2;
    3429           5 :         bool ret = false;
    3430           0 :         bool ok;
    3431           5 :         uint8_t data = 1;
    3432           0 :         NTSTATUS status;
    3433             : 
    3434           5 :         printf("starting locktest12\n");
    3435             : 
    3436           5 :         ev = samba_tevent_context_init(NULL);
    3437           5 :         if (ev == NULL) {
    3438           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3439           0 :                 goto done;
    3440             :         }
    3441             : 
    3442           5 :         ok = torture_open_connection(&cli, 0);
    3443           5 :         if (!ok) {
    3444           0 :                 goto done;
    3445             :         }
    3446           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3447             : 
    3448           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3449           5 :         if (!NT_STATUS_IS_OK(status)) {
    3450           0 :                 d_fprintf(stderr,
    3451             :                           "cli_openx failed: %s\n",
    3452             :                           nt_errstr(status));
    3453           0 :                 goto done;
    3454             :         }
    3455             : 
    3456           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3457           5 :         if (!NT_STATUS_IS_OK(status)) {
    3458           0 :                 d_fprintf(stderr,
    3459             :                           "cli_openx failed: %s\n",
    3460             :                           nt_errstr(status));
    3461           0 :                 goto done;
    3462             :         }
    3463             : 
    3464           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3465           5 :         if (!NT_STATUS_IS_OK(status)) {
    3466           0 :                 d_fprintf(stderr,
    3467             :                           "cli_writeall failed: %s\n",
    3468             :                           nt_errstr(status));
    3469           0 :                 goto done;
    3470             :         }
    3471             : 
    3472           5 :         status = cli_locktype(
    3473             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3474           5 :         if (!NT_STATUS_IS_OK(status)) {
    3475           0 :                 d_fprintf(stderr,
    3476             :                           "cli_locktype failed: %s\n",
    3477             :                           nt_errstr(status));
    3478           0 :                 goto done;
    3479             :         }
    3480             : 
    3481           5 :         req = lock12_send(ev, ev, cli, fnum1, fnum2);
    3482           5 :         if (req == NULL) {
    3483           0 :                 d_fprintf(stderr, "lock12_send failed\n");
    3484           0 :                 goto done;
    3485             :         }
    3486             : 
    3487           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3488           5 :         if (!ok) {
    3489           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3490           0 :                 goto done;
    3491             :         }
    3492             : 
    3493           5 :         if (!NT_STATUS_IS_OK(status)) {
    3494           0 :                 d_fprintf(stderr,
    3495             :                           "tevent_req_poll_ntstatus returned %s\n",
    3496             :                           nt_errstr(status));
    3497           0 :                 goto done;
    3498             :         }
    3499             : 
    3500           5 :         status = lock12_recv(req);
    3501           5 :         if (!NT_STATUS_IS_OK(status)) {
    3502           4 :                 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
    3503           4 :                 goto done;
    3504             :         }
    3505             : 
    3506           1 :         ret = true;
    3507           5 : done:
    3508           5 :         if (cli != NULL) {
    3509           5 :                 torture_close_connection(cli);
    3510             :         }
    3511           5 :         return ret;
    3512             : }
    3513             : 
    3514             : struct lock_ntcancel_state {
    3515             :         struct timeval start;
    3516             :         struct smb1_lock_element lck;
    3517             :         struct tevent_req *subreq;
    3518             : };
    3519             : 
    3520             : static void lock_ntcancel_waited(struct tevent_req *subreq);
    3521             : static void lock_ntcancel_done(struct tevent_req *subreq);
    3522             : 
    3523           5 : static struct tevent_req *lock_ntcancel_send(
    3524             :         TALLOC_CTX *mem_ctx,
    3525             :         struct tevent_context *ev,
    3526             :         struct cli_state *cli,
    3527             :         uint16_t fnum)
    3528             : {
    3529           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3530           5 :         struct lock_ntcancel_state *state = NULL;
    3531             : 
    3532           5 :         req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
    3533           5 :         if (req == NULL) {
    3534           0 :                 return NULL;
    3535             :         }
    3536          10 :         state->lck = (struct smb1_lock_element) {
    3537           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3538             :         };
    3539           5 :         state->start = timeval_current();
    3540             : 
    3541          10 :         state->subreq = cli_lockingx_send(
    3542             :                 state,                          /* mem_ctx */
    3543             :                 ev,                             /* tevent_context */
    3544             :                 cli,                            /* cli */
    3545             :                 fnum,                           /* fnum */
    3546             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3547             :                 0,                              /* newoplocklevel */
    3548             :                 10000,                          /* timeout */
    3549             :                 0,                              /* num_unlocks */
    3550             :                 NULL,                           /* unlocks */
    3551             :                 1,                              /* num_locks */
    3552           5 :                 &state->lck);                    /* locks */
    3553           5 :         if (tevent_req_nomem(state->subreq, req)) {
    3554           0 :                 return tevent_req_post(req, ev);
    3555             :         }
    3556           5 :         tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
    3557             : 
    3558           5 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
    3559           5 :         if (tevent_req_nomem(subreq, req)) {
    3560           0 :                 return tevent_req_post(req, ev);
    3561             :         }
    3562           5 :         tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
    3563           5 :         return req;
    3564             : }
    3565             : 
    3566           5 : static void lock_ntcancel_waited(struct tevent_req *subreq)
    3567             : {
    3568           5 :         struct tevent_req *req = tevent_req_callback_data(
    3569             :                 subreq, struct tevent_req);
    3570           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3571             :                 req, struct lock_ntcancel_state);
    3572           0 :         bool ok;
    3573             : 
    3574           5 :         ok = tevent_wakeup_recv(subreq);
    3575           5 :         TALLOC_FREE(subreq);
    3576           5 :         if (!ok) {
    3577           0 :                 tevent_req_oom(req);
    3578           0 :                 return;
    3579             :         }
    3580             : 
    3581           5 :         ok = tevent_req_cancel(state->subreq);
    3582           5 :         if (!ok) {
    3583           0 :                 d_fprintf(stderr, "Could not cancel subreq\n");
    3584           0 :                 tevent_req_oom(req);
    3585           0 :                 return;
    3586             :         }
    3587             : }
    3588             : 
    3589           5 : static void lock_ntcancel_done(struct tevent_req *subreq)
    3590             : {
    3591           5 :         struct tevent_req *req = tevent_req_callback_data(
    3592             :                 subreq, struct tevent_req);
    3593           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3594             :                 req, struct lock_ntcancel_state);
    3595           0 :         NTSTATUS status;
    3596           0 :         double elapsed;
    3597             : 
    3598           5 :         status = cli_lockingx_recv(subreq);
    3599           5 :         TALLOC_FREE(subreq);
    3600             : 
    3601           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3602           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3603           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3604           0 :                 return;
    3605             :         }
    3606             : 
    3607           5 :         elapsed = timeval_elapsed(&state->start);
    3608             : 
    3609           5 :         if (elapsed > 3) {
    3610           0 :                 d_printf("cli_lockingx was too slow, cancel did not work\n");
    3611           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3612           0 :                 return;
    3613             :         }
    3614             : 
    3615           5 :         tevent_req_done(req);
    3616             : }
    3617             : 
    3618           5 : static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
    3619             : {
    3620           5 :         return tevent_req_simple_recv_ntstatus(req);
    3621             : }
    3622             : 
    3623           5 : static bool run_locktest13(int dummy)
    3624             : {
    3625           5 :         struct tevent_context *ev = NULL;
    3626           5 :         struct tevent_req *req = NULL;
    3627           5 :         struct cli_state *cli = NULL;
    3628           5 :         const char fname[] = "\\lockt13.lck";
    3629           0 :         uint16_t fnum1, fnum2;
    3630           5 :         bool ret = false;
    3631           0 :         bool ok;
    3632           5 :         uint8_t data = 1;
    3633           0 :         NTSTATUS status;
    3634             : 
    3635           5 :         printf("starting locktest13\n");
    3636             : 
    3637           5 :         ev = samba_tevent_context_init(NULL);
    3638           5 :         if (ev == NULL) {
    3639           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3640           0 :                 goto done;
    3641             :         }
    3642             : 
    3643           5 :         ok = torture_open_connection(&cli, 0);
    3644           5 :         if (!ok) {
    3645           0 :                 goto done;
    3646             :         }
    3647           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3648             : 
    3649           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3650           5 :         if (!NT_STATUS_IS_OK(status)) {
    3651           0 :                 d_fprintf(stderr,
    3652             :                           "cli_openx failed: %s\n",
    3653             :                           nt_errstr(status));
    3654           0 :                 goto done;
    3655             :         }
    3656             : 
    3657           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3658           5 :         if (!NT_STATUS_IS_OK(status)) {
    3659           0 :                 d_fprintf(stderr,
    3660             :                           "cli_openx failed: %s\n",
    3661             :                           nt_errstr(status));
    3662           0 :                 goto done;
    3663             :         }
    3664             : 
    3665           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3666           5 :         if (!NT_STATUS_IS_OK(status)) {
    3667           0 :                 d_fprintf(stderr,
    3668             :                           "cli_writeall failed: %s\n",
    3669             :                           nt_errstr(status));
    3670           0 :                 goto done;
    3671             :         }
    3672             : 
    3673           5 :         status = cli_locktype(
    3674             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3675           5 :         if (!NT_STATUS_IS_OK(status)) {
    3676           0 :                 d_fprintf(stderr,
    3677             :                           "cli_locktype failed: %s\n",
    3678             :                           nt_errstr(status));
    3679           0 :                 goto done;
    3680             :         }
    3681             : 
    3682           5 :         req = lock_ntcancel_send(ev, ev, cli, fnum2);
    3683           5 :         if (req == NULL) {
    3684           0 :                 d_fprintf(stderr, "lock_ntcancel_send failed\n");
    3685           0 :                 goto done;
    3686             :         }
    3687             : 
    3688           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3689           5 :         if (!ok) {
    3690           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3691           0 :                 goto done;
    3692             :         }
    3693             : 
    3694           5 :         if (!NT_STATUS_IS_OK(status)) {
    3695           0 :                 d_fprintf(stderr,
    3696             :                           "tevent_req_poll_ntstatus returned %s\n",
    3697             :                           nt_errstr(status));
    3698           0 :                 goto done;
    3699             :         }
    3700             : 
    3701           5 :         status = lock_ntcancel_recv(req);
    3702           5 :         if (!NT_STATUS_IS_OK(status)) {
    3703           0 :                 d_fprintf(stderr,
    3704             :                           "lock_ntcancel returned %s\n",
    3705             :                           nt_errstr(status));
    3706           0 :                 goto done;
    3707             :         }
    3708             : 
    3709           5 :         ret = true;
    3710           5 : done:
    3711           5 :         if (cli != NULL) {
    3712           5 :                 torture_close_connection(cli);
    3713             :         }
    3714           5 :         return ret;
    3715             : }
    3716             : 
    3717             : /*
    3718             : test whether fnums and tids open on one VC are available on another (a major
    3719             : security hole)
    3720             : */
    3721           5 : static bool run_fdpasstest(int dummy)
    3722             : {
    3723           0 :         struct cli_state *cli1, *cli2;
    3724           5 :         const char *fname = "\\fdpass.tst";
    3725           0 :         uint16_t fnum1;
    3726           0 :         char buf[1024];
    3727           0 :         NTSTATUS status;
    3728             : 
    3729           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    3730           0 :                 return False;
    3731             :         }
    3732           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3733           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    3734             : 
    3735           5 :         printf("starting fdpasstest\n");
    3736             : 
    3737           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3738             : 
    3739           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    3740             :                           &fnum1);
    3741           5 :         if (!NT_STATUS_IS_OK(status)) {
    3742           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3743           0 :                 return False;
    3744             :         }
    3745             : 
    3746           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
    3747             :                               13, NULL);
    3748           5 :         if (!NT_STATUS_IS_OK(status)) {
    3749           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3750           0 :                 return False;
    3751             :         }
    3752             : 
    3753           5 :         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
    3754           5 :         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
    3755           5 :         cli_setpid(cli2, cli_getpid(cli1));
    3756             : 
    3757           5 :         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
    3758           0 :                 printf("read succeeded! nasty security hole [%s]\n", buf);
    3759           0 :                 return false;
    3760             :         }
    3761             : 
    3762           5 :         cli_close(cli1, fnum1);
    3763           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3764             : 
    3765           5 :         torture_close_connection(cli1);
    3766           5 :         torture_close_connection(cli2);
    3767             : 
    3768           5 :         printf("finished fdpasstest\n");
    3769           5 :         return True;
    3770             : }
    3771             : 
    3772           5 : static bool run_fdsesstest(int dummy)
    3773             : {
    3774           0 :         struct cli_state *cli;
    3775           0 :         uint16_t new_vuid;
    3776           0 :         uint16_t saved_vuid;
    3777           0 :         uint32_t new_cnum;
    3778           0 :         uint32_t saved_cnum;
    3779           5 :         const char *fname = "\\fdsess.tst";
    3780           5 :         const char *fname1 = "\\fdsess1.tst";
    3781           0 :         uint16_t fnum1;
    3782           0 :         uint16_t fnum2;
    3783           0 :         char buf[1024];
    3784           5 :         bool ret = True;
    3785           0 :         NTSTATUS status;
    3786             : 
    3787           5 :         if (!torture_open_connection(&cli, 0))
    3788           0 :                 return False;
    3789           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3790             : 
    3791           5 :         if (!torture_cli_session_setup2(cli, &new_vuid))
    3792           0 :                 return False;
    3793             : 
    3794           5 :         saved_cnum = cli_state_get_tid(cli);
    3795           5 :         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
    3796           0 :                 return False;
    3797           5 :         new_cnum = cli_state_get_tid(cli);
    3798           5 :         cli_state_set_tid(cli, saved_cnum);
    3799             : 
    3800           5 :         printf("starting fdsesstest\n");
    3801             : 
    3802           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3803           5 :         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3804             : 
    3805           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    3806           5 :         if (!NT_STATUS_IS_OK(status)) {
    3807           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3808           0 :                 return False;
    3809             :         }
    3810             : 
    3811           5 :         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
    3812             :                               NULL);
    3813           5 :         if (!NT_STATUS_IS_OK(status)) {
    3814           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3815           0 :                 return False;
    3816             :         }
    3817             : 
    3818           5 :         saved_vuid = cli_state_get_uid(cli);
    3819           5 :         cli_state_set_uid(cli, new_vuid);
    3820             : 
    3821           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3822           0 :                 printf("read succeeded with different vuid! "
    3823             :                        "nasty security hole [%s]\n", buf);
    3824           0 :                 ret = false;
    3825             :         }
    3826             :         /* Try to open a file with different vuid, samba cnum. */
    3827           5 :         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
    3828           5 :                 printf("create with different vuid, same cnum succeeded.\n");
    3829           5 :                 cli_close(cli, fnum2);
    3830           5 :                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3831             :         } else {
    3832           0 :                 printf("create with different vuid, same cnum failed.\n");
    3833           0 :                 printf("This will cause problems with service clients.\n");
    3834           0 :                 ret = False;
    3835             :         }
    3836             : 
    3837           5 :         cli_state_set_uid(cli, saved_vuid);
    3838             : 
    3839             :         /* Try with same vuid, different cnum. */
    3840           5 :         cli_state_set_tid(cli, new_cnum);
    3841             : 
    3842           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3843           0 :                 printf("read succeeded with different cnum![%s]\n", buf);
    3844           0 :                 ret = false;
    3845             :         }
    3846             : 
    3847           5 :         cli_state_set_tid(cli, saved_cnum);
    3848           5 :         cli_close(cli, fnum1);
    3849           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3850             : 
    3851           5 :         torture_close_connection(cli);
    3852             : 
    3853           5 :         printf("finished fdsesstest\n");
    3854           5 :         return ret;
    3855             : }
    3856             : 
    3857             : /*
    3858             :   This test checks that 
    3859             : 
    3860             :   1) the server does not allow an unlink on a file that is open
    3861             : */
    3862           5 : static bool run_unlinktest(int dummy)
    3863             : {
    3864           0 :         struct cli_state *cli;
    3865           5 :         const char *fname = "\\unlink.tst";
    3866           0 :         uint16_t fnum;
    3867           5 :         bool correct = True;
    3868           0 :         NTSTATUS status;
    3869             : 
    3870           5 :         if (!torture_open_connection(&cli, 0)) {
    3871           0 :                 return False;
    3872             :         }
    3873             : 
    3874           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3875             : 
    3876           5 :         printf("starting unlink test\n");
    3877             : 
    3878           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3879             : 
    3880           5 :         cli_setpid(cli, 1);
    3881             : 
    3882           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    3883           5 :         if (!NT_STATUS_IS_OK(status)) {
    3884           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3885           0 :                 return False;
    3886             :         }
    3887             : 
    3888           5 :         status = cli_unlink(cli, fname,
    3889             :                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3890           5 :         if (NT_STATUS_IS_OK(status)) {
    3891           0 :                 printf("error: server allowed unlink on an open file\n");
    3892           0 :                 correct = False;
    3893             :         } else {
    3894           5 :                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
    3895           5 :                                       NT_STATUS_SHARING_VIOLATION);
    3896             :         }
    3897             : 
    3898           5 :         cli_close(cli, fnum);
    3899           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3900             : 
    3901           5 :         if (!torture_close_connection(cli)) {
    3902           0 :                 correct = False;
    3903             :         }
    3904             : 
    3905           5 :         printf("unlink test finished\n");
    3906             : 
    3907           5 :         return correct;
    3908             : }
    3909             : 
    3910             : 
    3911             : /*
    3912             : test how many open files this server supports on the one socket
    3913             : */
    3914           0 : static bool run_maxfidtest(int dummy)
    3915             : {
    3916           0 :         struct cli_state *cli;
    3917           0 :         fstring fname;
    3918           0 :         uint16_t fnums[0x11000];
    3919           0 :         int i;
    3920           0 :         int retries=4;
    3921           0 :         bool correct = True;
    3922           0 :         NTSTATUS status;
    3923             : 
    3924           0 :         cli = current_cli;
    3925             : 
    3926           0 :         if (retries <= 0) {
    3927           0 :                 printf("failed to connect\n");
    3928           0 :                 return False;
    3929             :         }
    3930             : 
    3931           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3932             : 
    3933           0 :         for (i=0; i<0x11000; i++) {
    3934           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3935           0 :                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
    3936             :                                   &fnums[i]);
    3937           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3938           0 :                         printf("open of %s failed (%s)\n", 
    3939             :                                fname, nt_errstr(status));
    3940           0 :                         printf("maximum fnum is %d\n", i);
    3941           0 :                         break;
    3942             :                 }
    3943           0 :                 printf("%6d\r", i);
    3944             :         }
    3945           0 :         printf("%6d\n", i);
    3946           0 :         i--;
    3947             : 
    3948           0 :         printf("cleaning up\n");
    3949           0 :         for (;i>=0;i--) {
    3950           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3951           0 :                 cli_close(cli, fnums[i]);
    3952             : 
    3953           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3954           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3955           0 :                         printf("unlink of %s failed (%s)\n", 
    3956             :                                fname, nt_errstr(status));
    3957           0 :                         correct = False;
    3958             :                 }
    3959           0 :                 printf("%6d\r", i);
    3960             :         }
    3961           0 :         printf("%6d\n", 0);
    3962             : 
    3963           0 :         printf("maxfid test finished\n");
    3964           0 :         if (!torture_close_connection(cli)) {
    3965           0 :                 correct = False;
    3966             :         }
    3967           0 :         return correct;
    3968             : }
    3969             : 
    3970             : /* generate a random buffer */
    3971           0 : static void rand_buf(char *buf, int len)
    3972             : {
    3973           0 :         while (len--) {
    3974           0 :                 *buf = (char)sys_random();
    3975           0 :                 buf++;
    3976             :         }
    3977           0 : }
    3978             : 
    3979             : /* send smb negprot commands, not reading the response */
    3980           0 : static bool run_negprot_nowait(int dummy)
    3981             : {
    3982           0 :         struct tevent_context *ev;
    3983           0 :         int i;
    3984           0 :         struct cli_state *cli;
    3985           0 :         bool correct = True;
    3986             : 
    3987           0 :         printf("starting negprot nowait test\n");
    3988             : 
    3989           0 :         ev = samba_tevent_context_init(talloc_tos());
    3990           0 :         if (ev == NULL) {
    3991           0 :                 return false;
    3992             :         }
    3993             : 
    3994           0 :         if (!(cli = open_nbt_connection())) {
    3995           0 :                 TALLOC_FREE(ev);
    3996           0 :                 return False;
    3997             :         }
    3998             : 
    3999           0 :         for (i=0;i<50000;i++) {
    4000           0 :                 struct tevent_req *req;
    4001             : 
    4002           0 :                 req = smbXcli_negprot_send(
    4003             :                         ev,
    4004             :                         ev,
    4005             :                         cli->conn,
    4006           0 :                         cli->timeout,
    4007             :                         PROTOCOL_CORE,
    4008             :                         PROTOCOL_NT1,
    4009             :                         0,
    4010             :                         NULL);
    4011           0 :                 if (req == NULL) {
    4012           0 :                         TALLOC_FREE(ev);
    4013           0 :                         return false;
    4014             :                 }
    4015           0 :                 if (!tevent_req_poll(req, ev)) {
    4016           0 :                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
    4017           0 :                                   strerror(errno));
    4018           0 :                         TALLOC_FREE(ev);
    4019           0 :                         return false;
    4020             :                 }
    4021           0 :                 TALLOC_FREE(req);
    4022             :         }
    4023             : 
    4024           0 :         if (torture_close_connection(cli)) {
    4025           0 :                 correct = False;
    4026             :         }
    4027             : 
    4028           0 :         printf("finished negprot nowait test\n");
    4029             : 
    4030           0 :         return correct;
    4031             : }
    4032             : 
    4033             : /* send smb negprot commands, not reading the response */
    4034           4 : static bool run_bad_nbt_session(int dummy)
    4035             : {
    4036           0 :         struct nmb_name called, calling;
    4037           0 :         struct sockaddr_storage ss;
    4038           0 :         NTSTATUS status;
    4039           0 :         int fd;
    4040           0 :         bool ret;
    4041             : 
    4042           4 :         printf("starting bad nbt session test\n");
    4043             : 
    4044           4 :         make_nmb_name(&calling, myname, 0x0);
    4045           4 :         make_nmb_name(&called , host, 0x20);
    4046             : 
    4047           4 :         if (!resolve_name(host, &ss, 0x20, true)) {
    4048           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
    4049           0 :                 return false;
    4050             :         }
    4051             : 
    4052           4 :         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
    4053           4 :         if (!NT_STATUS_IS_OK(status)) {
    4054           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4055             :                           nt_errstr(status));
    4056           0 :                 return false;
    4057             :         }
    4058             : 
    4059           4 :         ret = cli_bad_session_request(fd, &calling, &called);
    4060           4 :         close(fd);
    4061           4 :         if (!ret) {
    4062           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4063             :                           nt_errstr(status));
    4064           0 :                 return false;
    4065             :         }
    4066             : 
    4067           4 :         printf("finished bad nbt session test\n");
    4068           4 :         return true;
    4069             : }
    4070             : 
    4071             : /* send random IPC commands */
    4072           0 : static bool run_randomipc(int dummy)
    4073             : {
    4074           0 :         char *rparam = NULL;
    4075           0 :         char *rdata = NULL;
    4076           0 :         unsigned int rdrcnt,rprcnt;
    4077           0 :         char param[1024];
    4078           0 :         int api, param_len, i;
    4079           0 :         struct cli_state *cli;
    4080           0 :         bool correct = True;
    4081           0 :         int count = 50000;
    4082             : 
    4083           0 :         printf("starting random ipc test\n");
    4084             : 
    4085           0 :         if (!torture_open_connection(&cli, 0)) {
    4086           0 :                 return False;
    4087             :         }
    4088             : 
    4089           0 :         for (i=0;i<count;i++) {
    4090           0 :                 api = sys_random() % 500;
    4091           0 :                 param_len = (sys_random() % 64);
    4092             : 
    4093           0 :                 rand_buf(param, param_len);
    4094             : 
    4095           0 :                 SSVAL(param,0,api); 
    4096             : 
    4097           0 :                 cli_api(cli, 
    4098             :                         param, param_len, 8,  
    4099             :                         NULL, 0, CLI_BUFFER_SIZE,
    4100             :                         &rparam, &rprcnt,     
    4101             :                         &rdata, &rdrcnt);
    4102           0 :                 if (i % 100 == 0) {
    4103           0 :                         printf("%d/%d\r", i,count);
    4104             :                 }
    4105             :         }
    4106           0 :         printf("%d/%d\n", i, count);
    4107             : 
    4108           0 :         if (!torture_close_connection(cli)) {
    4109           0 :                 correct = False;
    4110             :         }
    4111             : 
    4112           0 :         SAFE_FREE(rparam);
    4113           0 :         SAFE_FREE(rdata);
    4114             : 
    4115           0 :         printf("finished random ipc test\n");
    4116             : 
    4117           0 :         return correct;
    4118             : }
    4119             : 
    4120             : 
    4121             : 
    4122           8 : static void browse_callback(const char *sname, uint32_t stype,
    4123             :                             const char *comment, void *state)
    4124             : {
    4125           8 :         printf("\t%20.20s %08x %s\n", sname, stype, comment);
    4126           8 : }
    4127             : 
    4128             : 
    4129             : 
    4130             : /*
    4131             :   This test checks the browse list code
    4132             : 
    4133             : */
    4134           5 : static bool run_browsetest(int dummy)
    4135             : {
    4136           0 :         static struct cli_state *cli;
    4137           5 :         bool correct = True;
    4138             : 
    4139           5 :         printf("starting browse test\n");
    4140             : 
    4141           5 :         if (!torture_open_connection(&cli, 0)) {
    4142           0 :                 return False;
    4143             :         }
    4144             : 
    4145           5 :         printf("domain list:\n");
    4146           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    4147             :                           SV_TYPE_DOMAIN_ENUM,
    4148             :                           browse_callback, NULL);
    4149             : 
    4150           5 :         printf("machine list:\n");
    4151           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    4152             :                           SV_TYPE_ALL,
    4153             :                           browse_callback, NULL);
    4154             : 
    4155           5 :         if (!torture_close_connection(cli)) {
    4156           0 :                 correct = False;
    4157             :         }
    4158             : 
    4159           5 :         printf("browse test finished\n");
    4160             : 
    4161           5 :         return correct;
    4162             : 
    4163             : }
    4164             : 
    4165          20 : static bool check_attributes(struct cli_state *cli,
    4166             :                                 const char *fname,
    4167             :                                 uint32_t expected_attrs)
    4168             : {
    4169          20 :         uint32_t attrs = 0;
    4170          20 :         NTSTATUS status = cli_getatr(cli,
    4171             :                                 fname,
    4172             :                                 &attrs,
    4173             :                                 NULL,
    4174             :                                 NULL);
    4175          20 :         if (!NT_STATUS_IS_OK(status)) {
    4176           0 :                 printf("cli_getatr failed with %s\n",
    4177             :                         nt_errstr(status));
    4178           0 :                 return false;
    4179             :         }
    4180          20 :         if (attrs != expected_attrs) {
    4181           0 :                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
    4182             :                         (unsigned int)attrs,
    4183             :                         (unsigned int)expected_attrs);
    4184           0 :                 return false;
    4185             :         }
    4186          20 :         return true;
    4187             : }
    4188             : 
    4189             : /*
    4190             :   This checks how the getatr calls works
    4191             : */
    4192           5 : static bool run_attrtest(int dummy)
    4193             : {
    4194           0 :         struct cli_state *cli;
    4195           0 :         uint16_t fnum;
    4196           0 :         time_t t, t2;
    4197           5 :         const char *fname = "\\attrib123456789.tst";
    4198           5 :         bool correct = True;
    4199           0 :         NTSTATUS status;
    4200             : 
    4201           5 :         printf("starting attrib test\n");
    4202             : 
    4203           5 :         if (!torture_open_connection(&cli, 0)) {
    4204           0 :                 return False;
    4205             :         }
    4206             : 
    4207             :         /* Ensure we can't unlink with out-of-range (unknown) attribute. */
    4208           5 :         status = cli_unlink(cli, fname, 0x20000);
    4209           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4210           0 :                 correct = false;
    4211           0 :                 goto out;
    4212             :         }
    4213             : 
    4214           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4215           5 :         cli_openx(cli, fname, 
    4216             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4217           5 :         cli_close(cli, fnum);
    4218             : 
    4219           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4220           5 :         if (!NT_STATUS_IS_OK(status)) {
    4221           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4222           0 :                 correct = False;
    4223             :         }
    4224             : 
    4225           5 :         if (labs(t - time(NULL)) > 60*60*24*10) {
    4226           0 :                 printf("ERROR: SMBgetatr bug. time is %s",
    4227             :                        ctime(&t));
    4228           0 :                 t = time(NULL);
    4229           0 :                 correct = True;
    4230             :         }
    4231             : 
    4232           5 :         t2 = t-60*60*24; /* 1 day ago */
    4233             : 
    4234             :         /* Ensure we can't set with out-of-range (unknown) attribute. */
    4235           5 :         status = cli_setatr(cli, fname, 0x20000, t2);
    4236           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4237           0 :                 correct = false;
    4238           0 :                 goto out;
    4239             :         }
    4240             : 
    4241           5 :         status = cli_setatr(cli, fname, 0, t2);
    4242           5 :         if (!NT_STATUS_IS_OK(status)) {
    4243           0 :                 printf("setatr failed (%s)\n", nt_errstr(status));
    4244           0 :                 correct = True;
    4245             :         }
    4246             : 
    4247           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4248           5 :         if (!NT_STATUS_IS_OK(status)) {
    4249           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4250           0 :                 correct = True;
    4251             :         }
    4252             : 
    4253           5 :         if (t != t2) {
    4254           0 :                 printf("ERROR: getatr/setatr bug. times are\n%s",
    4255             :                        ctime(&t));
    4256           0 :                 printf("%s", ctime(&t2));
    4257           0 :                 correct = True;
    4258             :         }
    4259             : 
    4260           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4261             : 
    4262             :         /* Check cli_setpathinfo_ext() */
    4263             :         /* Re-create the file. */
    4264           5 :         status = cli_openx(cli, fname,
    4265             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4266           5 :         if (!NT_STATUS_IS_OK(status)) {
    4267           0 :                 printf("Failed to recreate %s (%s)\n",
    4268             :                         fname, nt_errstr(status));
    4269           0 :                 correct = false;
    4270             :         }
    4271           5 :         cli_close(cli, fnum);
    4272             : 
    4273           5 :         status = cli_setpathinfo_ext(
    4274             :                 cli,
    4275             :                 fname,
    4276           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4277           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4278           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4279           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4280             :                 FILE_ATTRIBUTE_SYSTEM |
    4281             :                 FILE_ATTRIBUTE_HIDDEN |
    4282             :                 FILE_ATTRIBUTE_READONLY);
    4283           5 :         if (!NT_STATUS_IS_OK(status)) {
    4284           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4285             :                         nt_errstr(status));
    4286           0 :                 correct = false;
    4287             :         }
    4288             : 
    4289             :         /* Check attributes are correct. */
    4290           5 :         correct = check_attributes(cli,
    4291             :                         fname,
    4292             :                         FILE_ATTRIBUTE_SYSTEM |
    4293             :                         FILE_ATTRIBUTE_HIDDEN |
    4294             :                         FILE_ATTRIBUTE_READONLY);
    4295           5 :         if (correct == false) {
    4296           0 :                 goto out;
    4297             :         }
    4298             : 
    4299             :         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
    4300           5 :         status = cli_setpathinfo_ext(
    4301             :                 cli,
    4302             :                 fname,
    4303           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4304           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4305           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4306           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4307             :                 FILE_ATTRIBUTE_NORMAL);
    4308           5 :         if (!NT_STATUS_IS_OK(status)) {
    4309           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4310             :                         nt_errstr(status));
    4311           0 :                 correct = false;
    4312             :         }
    4313             : 
    4314             :         /* Check attributes are correct. */
    4315           5 :         correct = check_attributes(cli,
    4316             :                         fname,
    4317             :                         FILE_ATTRIBUTE_SYSTEM |
    4318             :                         FILE_ATTRIBUTE_HIDDEN |
    4319             :                         FILE_ATTRIBUTE_READONLY);
    4320           5 :         if (correct == false) {
    4321           0 :                 goto out;
    4322             :         }
    4323             : 
    4324             :         /* Setting to (uint16_t)-1 should also be ignored. */
    4325           5 :         status = cli_setpathinfo_ext(
    4326             :                 cli,
    4327             :                 fname,
    4328           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4329           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4330           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4331           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4332             :                 (uint32_t)-1);
    4333           5 :         if (!NT_STATUS_IS_OK(status)) {
    4334           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4335             :                         nt_errstr(status));
    4336           0 :                 correct = false;
    4337             :         }
    4338             : 
    4339             :         /* Check attributes are correct. */
    4340           5 :         correct = check_attributes(cli,
    4341             :                         fname,
    4342             :                         FILE_ATTRIBUTE_SYSTEM |
    4343             :                         FILE_ATTRIBUTE_HIDDEN |
    4344             :                         FILE_ATTRIBUTE_READONLY);
    4345           5 :         if (correct == false) {
    4346           0 :                 goto out;
    4347             :         }
    4348             : 
    4349             :         /* Setting to 0 should clear them all. */
    4350           5 :         status = cli_setpathinfo_ext(
    4351             :                 cli,
    4352             :                 fname,
    4353           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4354           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4355           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4356           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4357             :                 0);
    4358           5 :         if (!NT_STATUS_IS_OK(status)) {
    4359           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4360             :                         nt_errstr(status));
    4361           0 :                 correct = false;
    4362             :         }
    4363             : 
    4364             :         /* Check attributes are correct. */
    4365           5 :         correct = check_attributes(cli,
    4366             :                         fname,
    4367             :                         FILE_ATTRIBUTE_NORMAL);
    4368           5 :         if (correct == false) {
    4369           0 :                 goto out;
    4370             :         }
    4371             : 
    4372           5 :   out:
    4373             : 
    4374           5 :         cli_unlink(cli,
    4375             :                 fname,
    4376             :                 FILE_ATTRIBUTE_SYSTEM |
    4377             :                 FILE_ATTRIBUTE_HIDDEN|
    4378             :                 FILE_ATTRIBUTE_READONLY);
    4379             : 
    4380           5 :         if (!torture_close_connection(cli)) {
    4381           0 :                 correct = False;
    4382             :         }
    4383             : 
    4384           5 :         printf("attrib test finished\n");
    4385             : 
    4386           5 :         return correct;
    4387             : }
    4388             : 
    4389           5 : static NTSTATUS cli_qfilename(
    4390             :         struct cli_state *cli,
    4391             :         uint16_t fnum,
    4392             :         TALLOC_CTX *mem_ctx,
    4393             :         char **_name)
    4394             : {
    4395           0 :         uint16_t recv_flags2;
    4396           0 :         uint8_t *rdata;
    4397           0 :         uint32_t num_rdata;
    4398           0 :         NTSTATUS status;
    4399           5 :         char *name = NULL;
    4400           0 :         uint32_t namelen;
    4401             : 
    4402           5 :         status = cli_qfileinfo(talloc_tos(), cli, fnum,
    4403             :                                SMB_QUERY_FILE_NAME_INFO,
    4404             :                                4, CLI_BUFFER_SIZE, &recv_flags2,
    4405             :                                &rdata, &num_rdata);
    4406           5 :         if (!NT_STATUS_IS_OK(status)) {
    4407           0 :                 return status;
    4408             :         }
    4409             : 
    4410           5 :         namelen = IVAL(rdata, 0);
    4411           5 :         if (namelen > (num_rdata - 4)) {
    4412           0 :                 TALLOC_FREE(rdata);
    4413           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    4414             :         }
    4415             : 
    4416           5 :         pull_string_talloc(mem_ctx,
    4417             :                            (const char *)rdata,
    4418             :                            recv_flags2,
    4419             :                            &name,
    4420           5 :                            rdata + 4,
    4421             :                            namelen,
    4422             :                            STR_UNICODE);
    4423           5 :         if (name == NULL) {
    4424           0 :                 status = map_nt_error_from_unix(errno);
    4425           0 :                 TALLOC_FREE(rdata);
    4426           0 :                 return status;
    4427             :         }
    4428             : 
    4429           5 :         *_name = name;
    4430           5 :         TALLOC_FREE(rdata);
    4431           5 :         return NT_STATUS_OK;
    4432             : }
    4433             : 
    4434             : /*
    4435             :   This checks a couple of trans2 calls
    4436             : */
    4437           5 : static bool run_trans2test(int dummy)
    4438             : {
    4439           0 :         struct cli_state *cli;
    4440           0 :         uint16_t fnum;
    4441           0 :         off_t size;
    4442           0 :         time_t c_time, a_time, m_time;
    4443           0 :         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
    4444           5 :         const char *fname = "\\trans2.tst";
    4445           5 :         const char *dname = "\\trans2";
    4446           5 :         const char *fname2 = "\\trans2\\trans2.tst";
    4447           5 :         char *pname = NULL;
    4448           5 :         bool correct = True;
    4449           0 :         NTSTATUS status;
    4450           0 :         uint32_t fs_attr;
    4451           0 :         uint64_t ino;
    4452             : 
    4453           5 :         printf("starting trans2 test\n");
    4454             : 
    4455           5 :         if (!torture_open_connection(&cli, 0)) {
    4456           0 :                 return False;
    4457             :         }
    4458             : 
    4459           5 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4460             :                 /* Ensure ino is zero, SMB2 gets a real one. */
    4461           0 :                 ino = 0;
    4462             :         } else {
    4463             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
    4464           5 :                 ino = (uint64_t)-1;
    4465             :         }
    4466             : 
    4467           5 :         status = cli_get_fs_attr_info(cli, &fs_attr);
    4468           5 :         if (!NT_STATUS_IS_OK(status)) {
    4469           0 :                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
    4470             :                        nt_errstr(status));
    4471           0 :                 correct = false;
    4472             :         }
    4473             : 
    4474           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4475           5 :         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4476           5 :         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
    4477             :                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
    4478           5 :         if (!NT_STATUS_IS_OK(status)) {
    4479           0 :                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
    4480           0 :                 correct = False;
    4481             :         }
    4482             : 
    4483           5 :         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
    4484           5 :         if (!NT_STATUS_IS_OK(status)) {
    4485           0 :                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
    4486           0 :                 correct = False;
    4487             :         }
    4488           5 :         else if (strcmp(pname, fname)) {
    4489           0 :                 printf("qfilename gave different name? [%s] [%s]\n",
    4490             :                        fname, pname);
    4491           0 :                 correct = False;
    4492             :         }
    4493             : 
    4494           5 :         cli_close(cli, fnum);
    4495             : 
    4496           5 :         sleep(2);
    4497             : 
    4498           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4499           5 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
    4500             :                           &fnum);
    4501           5 :         if (!NT_STATUS_IS_OK(status)) {
    4502           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4503           0 :                 return False;
    4504             :         }
    4505           5 :         cli_close(cli, fnum);
    4506             : 
    4507           5 :         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
    4508             :                                 NULL);
    4509           5 :         if (!NT_STATUS_IS_OK(status)) {
    4510           0 :                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
    4511           0 :                 correct = False;
    4512             :         } else {
    4513           5 :                 time_t t = time(NULL);
    4514             : 
    4515           5 :                 if (c_time != m_time) {
    4516           0 :                         printf("create time=%s", ctime(&c_time));
    4517           0 :                         printf("modify time=%s", ctime(&m_time));
    4518           0 :                         printf("This system appears to have sticky create times\n");
    4519             :                 }
    4520           5 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
    4521           0 :                         printf("access time=%s", ctime(&a_time));
    4522           0 :                         printf("This system appears to set a midnight access time\n");
    4523           0 :                         correct = False;
    4524             :                 }
    4525             : 
    4526           5 :                 if (labs(m_time - t) > 60*60*24*7) {
    4527           0 :                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
    4528           0 :                         correct = False;
    4529             :                 }
    4530             :         }
    4531             : 
    4532             : 
    4533           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4534           5 :         cli_openx(cli, fname, 
    4535             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4536           5 :         cli_close(cli, fnum);
    4537           5 :         status = cli_qpathinfo2(cli,
    4538             :                                 fname,
    4539             :                                 &c_time_ts,
    4540             :                                 &a_time_ts,
    4541             :                                 &w_time_ts,
    4542             :                                 &m_time_ts,
    4543             :                                 &size,
    4544             :                                 NULL,
    4545             :                                 &ino,
    4546             :                                 NULL);
    4547           5 :         if (!NT_STATUS_IS_OK(status)) {
    4548           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4549           0 :                 correct = False;
    4550             :         } else {
    4551           5 :                 if (w_time_ts.tv_sec < 60*60*24*2) {
    4552           0 :                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
    4553           0 :                         printf("This system appears to set a initial 0 write time\n");
    4554           0 :                         correct = False;
    4555             :                 }
    4556           5 :                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4557             :                         /* SMB2 should always return an inode. */
    4558           0 :                         if (ino == 0) {
    4559           0 :                                 printf("SMB2 bad inode (0)\n");
    4560           0 :                                 correct = false;
    4561             :                         }
    4562             :                 } else {
    4563             :                         /* SMB1 must always return zero here. */
    4564           5 :                         if (ino != 0) {
    4565           0 :                                 printf("SMB1 bad inode (!0)\n");
    4566           0 :                                 correct = false;
    4567             :                         }
    4568             :                 }
    4569             :         }
    4570             : 
    4571           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4572             : 
    4573             : 
    4574             :         /* check if the server updates the directory modification time
    4575             :            when creating a new file */
    4576           5 :         status = cli_mkdir(cli, dname);
    4577           5 :         if (!NT_STATUS_IS_OK(status)) {
    4578           0 :                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
    4579           0 :                 correct = False;
    4580             :         }
    4581           5 :         sleep(3);
    4582           5 :         status = cli_qpathinfo2(cli,
    4583             :                                 "\\trans2\\",
    4584             :                                 &c_time_ts,
    4585             :                                 &a_time_ts,
    4586             :                                 &w_time_ts,
    4587             :                                 &m_time_ts,
    4588             :                                 &size,
    4589             :                                 NULL,
    4590             :                                 NULL,
    4591             :                                 NULL);
    4592           5 :         if (!NT_STATUS_IS_OK(status)) {
    4593           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4594           0 :                 correct = False;
    4595             :         }
    4596             : 
    4597           5 :         cli_openx(cli, fname2, 
    4598             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4599           5 :         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
    4600           5 :         cli_close(cli, fnum);
    4601           5 :         status = cli_qpathinfo2(cli,
    4602             :                                 "\\trans2\\",
    4603             :                                 &c_time_ts,
    4604             :                                 &a_time_ts,
    4605             :                                 &w_time_ts,
    4606             :                                 &m_time2_ts,
    4607             :                                 &size,
    4608             :                                 NULL,
    4609             :                                 NULL,
    4610             :                                 NULL);
    4611           5 :         if (!NT_STATUS_IS_OK(status)) {
    4612           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4613           0 :                 correct = False;
    4614             :         } else {
    4615           5 :                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
    4616             :                     == 0) {
    4617           0 :                         printf("This system does not update directory modification times\n");
    4618           0 :                         correct = False;
    4619             :                 }
    4620             :         }
    4621           5 :         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4622           5 :         cli_rmdir(cli, dname);
    4623             : 
    4624           5 :         if (!torture_close_connection(cli)) {
    4625           0 :                 correct = False;
    4626             :         }
    4627             : 
    4628           5 :         printf("trans2 test finished\n");
    4629             : 
    4630           5 :         return correct;
    4631             : }
    4632             : 
    4633             : /*
    4634             :   This checks new W2K calls.
    4635             : */
    4636             : 
    4637         180 : static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
    4638             : {
    4639         180 :         uint8_t *buf = NULL;
    4640           0 :         uint32_t len;
    4641           0 :         NTSTATUS status;
    4642             : 
    4643         180 :         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
    4644             :                                CLI_BUFFER_SIZE, NULL, &buf, &len);
    4645         180 :         if (!NT_STATUS_IS_OK(status)) {
    4646         180 :                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
    4647             :                        nt_errstr(status));
    4648             :         } else {
    4649           0 :                 printf("qfileinfo: level %d, len = %u\n", level, len);
    4650           0 :                 dump_data(0, (uint8_t *)buf, len);
    4651           0 :                 printf("\n");
    4652             :         }
    4653         180 :         TALLOC_FREE(buf);
    4654         180 :         return status;
    4655             : }
    4656             : 
    4657           5 : static bool run_w2ktest(int dummy)
    4658             : {
    4659           0 :         struct cli_state *cli;
    4660           0 :         uint16_t fnum;
    4661           5 :         const char *fname = "\\w2ktest\\w2k.tst";
    4662           0 :         int level;
    4663           5 :         bool correct = True;
    4664             : 
    4665           5 :         printf("starting w2k test\n");
    4666             : 
    4667           5 :         if (!torture_open_connection(&cli, 0)) {
    4668           0 :                 return False;
    4669             :         }
    4670             : 
    4671           5 :         cli_openx(cli, fname, 
    4672             :                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
    4673             : 
    4674         185 :         for (level = 1004; level < 1040; level++) {
    4675         180 :                 new_trans(cli, fnum, level);
    4676             :         }
    4677             : 
    4678           5 :         cli_close(cli, fnum);
    4679             : 
    4680           5 :         if (!torture_close_connection(cli)) {
    4681           0 :                 correct = False;
    4682             :         }
    4683             : 
    4684           5 :         printf("w2k test finished\n");
    4685             : 
    4686           5 :         return correct;
    4687             : }
    4688             : 
    4689             : 
    4690             : /*
    4691             :   this is a harness for some oplock tests
    4692             :  */
    4693           5 : static bool run_oplock1(int dummy)
    4694             : {
    4695           0 :         struct cli_state *cli1;
    4696           5 :         const char *fname = "\\lockt1.lck";
    4697           0 :         uint16_t fnum1;
    4698           5 :         bool correct = True;
    4699           0 :         NTSTATUS status;
    4700             : 
    4701           5 :         printf("starting oplock test 1\n");
    4702             : 
    4703           5 :         if (!torture_open_connection(&cli1, 0)) {
    4704           0 :                 return False;
    4705             :         }
    4706             : 
    4707           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4708             : 
    4709           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4710             : 
    4711           5 :         cli1->use_oplocks = True;
    4712             : 
    4713           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4714             :                           &fnum1);
    4715           5 :         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           5 :         cli1->use_oplocks = False;
    4721             : 
    4722           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4723           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4724             : 
    4725           5 :         status = cli_close(cli1, fnum1);
    4726           5 :         if (!NT_STATUS_IS_OK(status)) {
    4727           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4728           0 :                 return False;
    4729             :         }
    4730             : 
    4731           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4732           5 :         if (!NT_STATUS_IS_OK(status)) {
    4733           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4734           0 :                 return False;
    4735             :         }
    4736             : 
    4737           5 :         if (!torture_close_connection(cli1)) {
    4738           0 :                 correct = False;
    4739             :         }
    4740             : 
    4741           5 :         printf("finished oplock test 1\n");
    4742             : 
    4743           5 :         return correct;
    4744             : }
    4745             : 
    4746           4 : static bool run_oplock2(int dummy)
    4747             : {
    4748           0 :         struct cli_state *cli1, *cli2;
    4749           4 :         const char *fname = "\\lockt2.lck";
    4750           0 :         uint16_t fnum1, fnum2;
    4751           4 :         int saved_use_oplocks = use_oplocks;
    4752           0 :         char buf[4];
    4753           4 :         bool correct = True;
    4754           0 :         volatile bool *shared_correct;
    4755           0 :         size_t nread;
    4756           0 :         NTSTATUS status;
    4757             : 
    4758           4 :         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
    4759           4 :         *shared_correct = True;
    4760             : 
    4761           4 :         use_level_II_oplocks = True;
    4762           4 :         use_oplocks = True;
    4763             : 
    4764           4 :         printf("starting oplock test 2\n");
    4765             : 
    4766           4 :         if (!torture_open_connection(&cli1, 0)) {
    4767           0 :                 use_level_II_oplocks = False;
    4768           0 :                 use_oplocks = saved_use_oplocks;
    4769           0 :                 return False;
    4770             :         }
    4771             : 
    4772           4 :         if (!torture_open_connection(&cli2, 1)) {
    4773           0 :                 use_level_II_oplocks = False;
    4774           0 :                 use_oplocks = saved_use_oplocks;
    4775           0 :                 return False;
    4776             :         }
    4777             : 
    4778           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4779             : 
    4780           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4781           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4782             : 
    4783           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4784             :                           &fnum1);
    4785           4 :         if (!NT_STATUS_IS_OK(status)) {
    4786           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4787           0 :                 return False;
    4788             :         }
    4789             : 
    4790             :         /* Don't need the globals any more. */
    4791           4 :         use_level_II_oplocks = False;
    4792           4 :         use_oplocks = saved_use_oplocks;
    4793             : 
    4794           4 :         if (fork() == 0) {
    4795             :                 /* Child code */
    4796           4 :                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    4797           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4798           0 :                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
    4799           0 :                         *shared_correct = False;
    4800           0 :                         exit(0);
    4801             :                 }
    4802             : 
    4803           4 :                 sleep(2);
    4804             : 
    4805           4 :                 status = cli_close(cli2, fnum2);
    4806           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4807           0 :                         printf("close2 failed (%s)\n", nt_errstr(status));
    4808           0 :                         *shared_correct = False;
    4809             :                 }
    4810             : 
    4811           4 :                 exit(0);
    4812             :         }
    4813             : 
    4814           4 :         sleep(2);
    4815             : 
    4816             :         /* Ensure cli1 processes the break. Empty file should always return 0
    4817             :          * bytes.  */
    4818           4 :         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
    4819           4 :         if (!NT_STATUS_IS_OK(status)) {
    4820           0 :                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
    4821           0 :                 correct = false;
    4822           4 :         } else if (nread != 0) {
    4823           0 :                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
    4824             :                       (unsigned long)nread, 0);
    4825           0 :                 correct = false;
    4826             :         }
    4827             : 
    4828             :         /* Should now be at level II. */
    4829             :         /* Test if sending a write locks causes a break to none. */
    4830           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
    4831           4 :         if (!NT_STATUS_IS_OK(status)) {
    4832           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4833           0 :                 correct = False;
    4834             :         }
    4835             : 
    4836           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4837             : 
    4838           4 :         sleep(2);
    4839             : 
    4840           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    4841           4 :         if (!NT_STATUS_IS_OK(status)) {
    4842           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4843           0 :                 correct = False;
    4844             :         }
    4845             : 
    4846           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4847             : 
    4848           4 :         sleep(2);
    4849             : 
    4850           4 :         cli_read(cli1, fnum1, buf, 0, 4, NULL);
    4851             : 
    4852           4 :         status = cli_close(cli1, fnum1);
    4853           4 :         if (!NT_STATUS_IS_OK(status)) {
    4854           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4855           0 :                 correct = False;
    4856             :         }
    4857             : 
    4858           4 :         sleep(4);
    4859             : 
    4860           4 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4861           4 :         if (!NT_STATUS_IS_OK(status)) {
    4862           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4863           0 :                 correct = False;
    4864             :         }
    4865             : 
    4866           4 :         if (!torture_close_connection(cli1)) {
    4867           0 :                 correct = False;
    4868             :         }
    4869             : 
    4870           4 :         if (!*shared_correct) {
    4871           0 :                 correct = False;
    4872             :         }
    4873             : 
    4874           4 :         printf("finished oplock test 2\n");
    4875             : 
    4876           4 :         return correct;
    4877             : }
    4878             : 
    4879             : struct oplock4_state {
    4880             :         struct tevent_context *ev;
    4881             :         struct cli_state *cli;
    4882             :         bool *got_break;
    4883             :         uint16_t *fnum2;
    4884             : };
    4885             : 
    4886             : static void oplock4_got_break(struct tevent_req *req);
    4887             : static void oplock4_got_open(struct tevent_req *req);
    4888             : 
    4889           5 : static bool run_oplock4(int dummy)
    4890             : {
    4891           0 :         struct tevent_context *ev;
    4892           0 :         struct cli_state *cli1, *cli2;
    4893           0 :         struct tevent_req *oplock_req, *open_req;
    4894           5 :         const char *fname = "\\lockt4.lck";
    4895           5 :         const char *fname_ln = "\\lockt4_ln.lck";
    4896           0 :         uint16_t fnum1, fnum2;
    4897           5 :         int saved_use_oplocks = use_oplocks;
    4898           0 :         NTSTATUS status;
    4899           5 :         bool correct = true;
    4900             : 
    4901           0 :         bool got_break;
    4902             : 
    4903           0 :         struct oplock4_state *state;
    4904             : 
    4905           5 :         printf("starting oplock test 4\n");
    4906             : 
    4907           5 :         if (!torture_open_connection(&cli1, 0)) {
    4908           0 :                 use_level_II_oplocks = false;
    4909           0 :                 use_oplocks = saved_use_oplocks;
    4910           0 :                 return false;
    4911             :         }
    4912             : 
    4913           5 :         if (!torture_open_connection(&cli2, 1)) {
    4914           0 :                 use_level_II_oplocks = false;
    4915           0 :                 use_oplocks = saved_use_oplocks;
    4916           0 :                 return false;
    4917             :         }
    4918             : 
    4919           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4920           5 :         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4921             : 
    4922           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4923           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4924             : 
    4925             :         /* Create the file. */
    4926           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4927             :                           &fnum1);
    4928           5 :         if (!NT_STATUS_IS_OK(status)) {
    4929           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4930           0 :                 return false;
    4931             :         }
    4932             : 
    4933           5 :         status = cli_close(cli1, fnum1);
    4934           5 :         if (!NT_STATUS_IS_OK(status)) {
    4935           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4936           0 :                 return false;
    4937             :         }
    4938             : 
    4939             :         /* Now create a hardlink. */
    4940           5 :         status = cli_hardlink(cli1, fname, fname_ln);
    4941           5 :         if (!NT_STATUS_IS_OK(status)) {
    4942           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    4943           0 :                 return false;
    4944             :         }
    4945             : 
    4946             :         /* Prove that opening hardlinks cause deny modes to conflict. */
    4947           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
    4948           5 :         if (!NT_STATUS_IS_OK(status)) {
    4949           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4950           0 :                 return false;
    4951             :         }
    4952             : 
    4953           5 :         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
    4954           5 :         if (NT_STATUS_IS_OK(status)) {
    4955           0 :                 printf("open of %s succeeded - should fail with sharing violation.\n",
    4956             :                         fname_ln);
    4957           0 :                 return false;
    4958             :         }
    4959             : 
    4960           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    4961           0 :                 printf("open of %s should fail with sharing violation. Got %s\n",
    4962             :                         fname_ln, nt_errstr(status));
    4963           0 :                 return false;
    4964             :         }
    4965             : 
    4966           5 :         status = cli_close(cli1, fnum1);
    4967           5 :         if (!NT_STATUS_IS_OK(status)) {
    4968           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4969           0 :                 return false;
    4970             :         }
    4971             : 
    4972           5 :         cli1->use_oplocks = true;
    4973           5 :         cli2->use_oplocks = true;
    4974             : 
    4975           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    4976           5 :         if (!NT_STATUS_IS_OK(status)) {
    4977           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4978           0 :                 return false;
    4979             :         }
    4980             : 
    4981           5 :         ev = samba_tevent_context_init(talloc_tos());
    4982           5 :         if (ev == NULL) {
    4983           0 :                 printf("tevent_context_init failed\n");
    4984           0 :                 return false;
    4985             :         }
    4986             : 
    4987           5 :         state = talloc(ev, struct oplock4_state);
    4988           5 :         if (state == NULL) {
    4989           0 :                 printf("talloc failed\n");
    4990           0 :                 return false;
    4991             :         }
    4992           5 :         state->ev = ev;
    4993           5 :         state->cli = cli1;
    4994           5 :         state->got_break = &got_break;
    4995           5 :         state->fnum2 = &fnum2;
    4996             : 
    4997           5 :         oplock_req = cli_smb_oplock_break_waiter_send(
    4998             :                 talloc_tos(), ev, cli1);
    4999           5 :         if (oplock_req == NULL) {
    5000           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    5001           0 :                 return false;
    5002             :         }
    5003           5 :         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
    5004             : 
    5005           5 :         open_req = cli_openx_send(
    5006             :                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
    5007           5 :         if (open_req == NULL) {
    5008           0 :                 printf("cli_openx_send failed\n");
    5009           0 :                 return false;
    5010             :         }
    5011           5 :         tevent_req_set_callback(open_req, oplock4_got_open, state);
    5012             : 
    5013           5 :         got_break = false;
    5014           5 :         fnum2 = 0xffff;
    5015             : 
    5016          40 :         while (!got_break || fnum2 == 0xffff) {
    5017           0 :                 int ret;
    5018          35 :                 ret = tevent_loop_once(ev);
    5019          35 :                 if (ret == -1) {
    5020           0 :                         printf("tevent_loop_once failed: %s\n",
    5021           0 :                                strerror(errno));
    5022           0 :                         return false;
    5023             :                 }
    5024             :         }
    5025             : 
    5026           5 :         status = cli_close(cli2, fnum2);
    5027           5 :         if (!NT_STATUS_IS_OK(status)) {
    5028           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    5029           0 :                 correct = false;
    5030             :         }
    5031             : 
    5032           5 :         status = cli_close(cli1, fnum1);
    5033           5 :         if (!NT_STATUS_IS_OK(status)) {
    5034           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    5035           0 :                 correct = false;
    5036             :         }
    5037             : 
    5038           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5039           5 :         if (!NT_STATUS_IS_OK(status)) {
    5040           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5041           0 :                 correct = false;
    5042             :         }
    5043             : 
    5044           5 :         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5045           5 :         if (!NT_STATUS_IS_OK(status)) {
    5046           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5047           0 :                 correct = false;
    5048             :         }
    5049             : 
    5050           5 :         if (!torture_close_connection(cli1)) {
    5051           0 :                 correct = false;
    5052             :         }
    5053             : 
    5054           5 :         if (!got_break) {
    5055           0 :                 correct = false;
    5056             :         }
    5057             : 
    5058           5 :         printf("finished oplock test 4\n");
    5059             : 
    5060           5 :         return correct;
    5061             : }
    5062             : 
    5063           5 : static void oplock4_got_break(struct tevent_req *req)
    5064             : {
    5065           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5066             :                 req, struct oplock4_state);
    5067           0 :         uint16_t fnum;
    5068           0 :         uint8_t level;
    5069           0 :         NTSTATUS status;
    5070             : 
    5071           5 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    5072           5 :         TALLOC_FREE(req);
    5073           5 :         if (!NT_STATUS_IS_OK(status)) {
    5074           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    5075             :                        nt_errstr(status));
    5076           0 :                 return;
    5077             :         }
    5078           5 :         *state->got_break = true;
    5079             : 
    5080           5 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    5081             :                                   NO_OPLOCK);
    5082           5 :         if (req == NULL) {
    5083           0 :                 printf("cli_oplock_ack_send failed\n");
    5084           0 :                 return;
    5085             :         }
    5086             : }
    5087             : 
    5088           5 : static void oplock4_got_open(struct tevent_req *req)
    5089             : {
    5090           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5091             :                 req, struct oplock4_state);
    5092           0 :         NTSTATUS status;
    5093             : 
    5094           5 :         status = cli_openx_recv(req, state->fnum2);
    5095           5 :         if (!NT_STATUS_IS_OK(status)) {
    5096           0 :                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
    5097           0 :                 *state->fnum2 = 0xffff;
    5098             :         }
    5099           5 : }
    5100             : 
    5101             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
    5102             : 
    5103             : struct oplock5_state {
    5104             :         int pipe_down_fd;
    5105             : };
    5106             : 
    5107             : /*
    5108             :  * Async open the file that has a kernel oplock, do an echo to get
    5109             :  * that 100% across, close the file to signal to the child fd that the
    5110             :  * oplock can be dropped, wait for the open reply.
    5111             :  */
    5112             : 
    5113             : static void oplock5_opened(struct tevent_req *subreq);
    5114             : static void oplock5_pong(struct tevent_req *subreq);
    5115             : static void oplock5_timedout(struct tevent_req *subreq);
    5116             : 
    5117           1 : static struct tevent_req *oplock5_send(
    5118             :         TALLOC_CTX *mem_ctx,
    5119             :         struct tevent_context *ev,
    5120             :         struct cli_state *cli,
    5121             :         const char *fname,
    5122             :         int pipe_down_fd)
    5123             : {
    5124           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    5125           1 :         struct oplock5_state *state = NULL;
    5126           0 :         static uint8_t data = 0;
    5127             : 
    5128           1 :         req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
    5129           1 :         if (req == NULL) {
    5130           0 :                 return NULL;
    5131             :         }
    5132           1 :         state->pipe_down_fd = pipe_down_fd;
    5133             : 
    5134           1 :         subreq = cli_ntcreate_send(
    5135             :                 state,
    5136             :                 ev,
    5137             :                 cli,
    5138             :                 fname,
    5139             :                 0,                      /* CreatFlags */
    5140             :                 SEC_FILE_READ_DATA,    /* DesiredAccess */
    5141             :                 FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
    5142             :                 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
    5143             :                 FILE_OPEN,               /* CreateDisposition */
    5144             :                 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
    5145             :                 0,                       /* Impersonation */
    5146             :                 0);                      /* SecurityFlags */
    5147           1 :         if (tevent_req_nomem(subreq, req)) {
    5148           0 :                 return tevent_req_post(req, ev);
    5149             :         }
    5150           1 :         tevent_req_set_callback(subreq, oplock5_opened, req);
    5151             : 
    5152           1 :         subreq = cli_echo_send(
    5153             :                 state,
    5154             :                 ev,
    5155             :                 cli,
    5156             :                 1,
    5157           1 :                 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
    5158           1 :         if (tevent_req_nomem(subreq, req)) {
    5159           0 :                 return tevent_req_post(req, ev);
    5160             :         }
    5161           1 :         tevent_req_set_callback(subreq, oplock5_pong, req);
    5162             : 
    5163           1 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
    5164           1 :         if (tevent_req_nomem(subreq, req)) {
    5165           0 :                 return tevent_req_post(req, ev);
    5166             :         }
    5167           1 :         tevent_req_set_callback(subreq, oplock5_timedout, req);
    5168             : 
    5169           1 :         return req;
    5170             : }
    5171             : 
    5172           1 : static void oplock5_opened(struct tevent_req *subreq)
    5173             : {
    5174           1 :         struct tevent_req *req = tevent_req_callback_data(
    5175             :                 subreq, struct tevent_req);
    5176           0 :         NTSTATUS status;
    5177           0 :         uint16_t fnum;
    5178             : 
    5179           1 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
    5180           1 :         TALLOC_FREE(subreq);
    5181           1 :         if (tevent_req_nterror(req, status)) {
    5182           0 :                 return;
    5183             :         }
    5184           1 :         tevent_req_done(req);
    5185             : }
    5186             : 
    5187           1 : static void oplock5_pong(struct tevent_req *subreq)
    5188             : {
    5189           1 :         struct tevent_req *req = tevent_req_callback_data(
    5190             :                 subreq, struct tevent_req);
    5191           1 :         struct oplock5_state *state = tevent_req_data(
    5192             :                 req, struct oplock5_state);
    5193           0 :         NTSTATUS status;
    5194             : 
    5195           1 :         status = cli_echo_recv(subreq);
    5196           1 :         TALLOC_FREE(subreq);
    5197           1 :         if (tevent_req_nterror(req, status)) {
    5198           0 :                 return;
    5199             :         }
    5200             : 
    5201           1 :         close(state->pipe_down_fd);
    5202             : }
    5203             : 
    5204           0 : static void oplock5_timedout(struct tevent_req *subreq)
    5205             : {
    5206           0 :         struct tevent_req *req = tevent_req_callback_data(
    5207             :                 subreq, struct tevent_req);
    5208           0 :         bool ok;
    5209             : 
    5210           0 :         ok = tevent_wakeup_recv(subreq);
    5211           0 :         TALLOC_FREE(subreq);
    5212           0 :         if (!ok) {
    5213           0 :                 tevent_req_oom(req);
    5214           0 :                 return;
    5215             :         }
    5216           0 :         tevent_req_nterror(req, NT_STATUS_TIMEOUT);
    5217             : }
    5218             : 
    5219           1 : static NTSTATUS oplock5_recv(struct tevent_req *req)
    5220             : {
    5221           1 :         return tevent_req_simple_recv_ntstatus(req);
    5222             : }
    5223             : 
    5224           1 : static bool run_oplock5(int dummy)
    5225             : {
    5226           1 :         struct tevent_context *ev = NULL;
    5227           1 :         struct tevent_req *req = NULL;
    5228           1 :         struct cli_state *cli = NULL;
    5229           1 :         const char *fname = "oplock5.txt";
    5230           0 :         int pipe_down[2], pipe_up[2];
    5231           0 :         pid_t child_pid;
    5232           1 :         uint8_t c = '\0';
    5233           0 :         NTSTATUS status;
    5234           0 :         int ret;
    5235           0 :         bool ok;
    5236             : 
    5237           1 :         printf("starting oplock5\n");
    5238             : 
    5239           1 :         if (local_path == NULL) {
    5240           0 :                 d_fprintf(stderr, "oplock5 must be given a local path via "
    5241             :                           "-l <localpath>\n");
    5242           0 :                 return false;
    5243             :         }
    5244             : 
    5245           1 :         ret = pipe(pipe_down);
    5246           1 :         if (ret == -1) {
    5247           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5248           0 :                 return false;
    5249             :         }
    5250           1 :         ret = pipe(pipe_up);
    5251           1 :         if (ret == -1) {
    5252           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5253           0 :                 return false;
    5254             :         }
    5255             : 
    5256           1 :         child_pid = fork();
    5257           2 :         if (child_pid == -1) {
    5258           0 :                 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
    5259           0 :                 return false;
    5260             :         }
    5261             : 
    5262           2 :         if (child_pid == 0) {
    5263           1 :                 char *local_file = NULL;
    5264           0 :                 int fd;
    5265             : 
    5266           1 :                 close(pipe_down[1]);
    5267           1 :                 close(pipe_up[0]);
    5268             : 
    5269           1 :                 local_file = talloc_asprintf(
    5270           1 :                         talloc_tos(), "%s/%s", local_path, fname);
    5271           1 :                 if (local_file == 0) {
    5272           0 :                         c = 1;
    5273           0 :                         goto do_write;
    5274             :                 }
    5275           1 :                 fd = open(local_file, O_RDWR|O_CREAT, 0644);
    5276           1 :                 if (fd == -1) {
    5277           0 :                         d_fprintf(stderr,
    5278             :                                   "open(%s) in child failed: %s\n",
    5279             :                                   local_file,
    5280           0 :                                   strerror(errno));
    5281           0 :                         c = 2;
    5282           0 :                         goto do_write;
    5283             :                 }
    5284             : 
    5285           1 :                 signal(SIGIO, SIG_IGN);
    5286             : 
    5287           1 :                 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
    5288           1 :                 if (ret == -1) {
    5289           0 :                         d_fprintf(stderr,
    5290             :                                   "SETLEASE in child failed: %s\n",
    5291           0 :                                   strerror(errno));
    5292           0 :                         c = 3;
    5293           0 :                         goto do_write;
    5294             :                 }
    5295             : 
    5296           1 :         do_write:
    5297           1 :                 ret = sys_write(pipe_up[1], &c, sizeof(c));
    5298           1 :                 if (ret == -1) {
    5299           0 :                         d_fprintf(stderr,
    5300             :                                   "sys_write failed: %s\n",
    5301           0 :                                   strerror(errno));
    5302           0 :                         exit(4);
    5303             :                 }
    5304           1 :                 ret = sys_read(pipe_down[0], &c, sizeof(c));
    5305           1 :                 if (ret == -1) {
    5306           0 :                         d_fprintf(stderr,
    5307             :                                   "sys_read failed: %s\n",
    5308           0 :                                   strerror(errno));
    5309           0 :                         exit(5);
    5310             :                 }
    5311           1 :                 exit(0);
    5312             :         }
    5313             : 
    5314           1 :         close(pipe_up[1]);
    5315           1 :         close(pipe_down[0]);
    5316             : 
    5317           1 :         ret = sys_read(pipe_up[0], &c, sizeof(c));
    5318           1 :         if (ret != 1) {
    5319           0 :                 d_fprintf(stderr,
    5320             :                           "sys_read failed: %s\n",
    5321           0 :                           strerror(errno));
    5322           0 :                 return false;
    5323             :         }
    5324           1 :         if (c != 0) {
    5325           0 :                 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
    5326           0 :                 return false;
    5327             :         }
    5328             : 
    5329           1 :         ok = torture_open_connection(&cli, 0);
    5330           1 :         if (!ok) {
    5331           0 :                 d_fprintf(stderr, "torture_open_connection failed\n");
    5332           0 :                 return false;
    5333             :         }
    5334             : 
    5335           1 :         ev = samba_tevent_context_init(talloc_tos());
    5336           1 :         if (ev == NULL) {
    5337           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5338           0 :                 return false;
    5339             :         }
    5340             : 
    5341           1 :         req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
    5342           1 :         if (req == NULL) {
    5343           0 :                 d_fprintf(stderr, "oplock5_send failed\n");
    5344           0 :                 return false;
    5345             :         }
    5346             : 
    5347           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5348           1 :         if (!ok) {
    5349           0 :                 d_fprintf(stderr,
    5350             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5351             :                           nt_errstr(status));
    5352           0 :                 return false;
    5353             :         }
    5354             : 
    5355           1 :         status = oplock5_recv(req);
    5356           1 :         TALLOC_FREE(req);
    5357           1 :         if (!NT_STATUS_IS_OK(status)) {
    5358           0 :                 d_fprintf(stderr,
    5359             :                           "oplock5 failed: %s\n",
    5360             :                           nt_errstr(status));
    5361           0 :                 return false;
    5362             :         }
    5363             : 
    5364           1 :         return true;
    5365             : }
    5366             : 
    5367             : #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
    5368             : 
    5369             : /*
    5370             :   Test delete on close semantics.
    5371             :  */
    5372           5 : static bool run_deletetest(int dummy)
    5373             : {
    5374           5 :         struct cli_state *cli1 = NULL;
    5375           5 :         struct cli_state *cli2 = NULL;
    5376           5 :         const char *fname = "\\delete.file";
    5377           5 :         uint16_t fnum1 = (uint16_t)-1;
    5378           5 :         uint16_t fnum2 = (uint16_t)-1;
    5379           5 :         bool correct = false;
    5380           0 :         NTSTATUS status;
    5381             : 
    5382           5 :         printf("starting delete test\n");
    5383             : 
    5384           5 :         if (!torture_open_connection(&cli1, 0)) {
    5385           0 :                 return False;
    5386             :         }
    5387             : 
    5388           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5389             : 
    5390             :         /* Test 1 - this should delete the file on close. */
    5391             : 
    5392           5 :         cli_setatr(cli1, fname, 0, 0);
    5393           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5394             : 
    5395           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5396             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5397             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5398           5 :         if (!NT_STATUS_IS_OK(status)) {
    5399           0 :                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
    5400           0 :                 goto fail;
    5401             :         }
    5402             : 
    5403           5 :         status = cli_close(cli1, fnum1);
    5404           5 :         if (!NT_STATUS_IS_OK(status)) {
    5405           0 :                 printf("[1] close failed (%s)\n", nt_errstr(status));
    5406           0 :                 goto fail;
    5407             :         }
    5408             : 
    5409           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    5410           5 :         if (NT_STATUS_IS_OK(status)) {
    5411           0 :                 printf("[1] open of %s succeeded (should fail)\n", fname);
    5412           0 :                 goto fail;
    5413             :         }
    5414             : 
    5415           5 :         printf("first delete on close test succeeded.\n");
    5416             : 
    5417             :         /* Test 2 - this should delete the file on close. */
    5418             : 
    5419           5 :         cli_setatr(cli1, fname, 0, 0);
    5420           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5421             : 
    5422           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5423             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5424             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5425           5 :         if (!NT_STATUS_IS_OK(status)) {
    5426           0 :                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
    5427           0 :                 goto fail;
    5428             :         }
    5429             : 
    5430           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5431           5 :         if (!NT_STATUS_IS_OK(status)) {
    5432           0 :                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5433           0 :                 goto fail;
    5434             :         }
    5435             : 
    5436           5 :         status = cli_close(cli1, fnum1);
    5437           5 :         if (!NT_STATUS_IS_OK(status)) {
    5438           0 :                 printf("[2] close failed (%s)\n", nt_errstr(status));
    5439           0 :                 goto fail;
    5440             :         }
    5441             : 
    5442           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5443           5 :         if (NT_STATUS_IS_OK(status)) {
    5444           0 :                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
    5445           0 :                 status = cli_close(cli1, fnum1);
    5446           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5447           0 :                         printf("[2] close failed (%s)\n", nt_errstr(status));
    5448             :                 }
    5449           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5450           0 :                 goto fail;
    5451             :         }
    5452             : 
    5453           5 :         printf("second delete on close test succeeded.\n");
    5454             : 
    5455             :         /* Test 3 - ... */
    5456           5 :         cli_setatr(cli1, fname, 0, 0);
    5457           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5458             : 
    5459           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5460             :                               FILE_ATTRIBUTE_NORMAL,
    5461             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5462             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5463           5 :         if (!NT_STATUS_IS_OK(status)) {
    5464           0 :                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5465           0 :                 goto fail;
    5466             :         }
    5467             : 
    5468             :         /* This should fail with a sharing violation - open for delete is only compatible
    5469             :            with SHARE_DELETE. */
    5470             : 
    5471           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5472             :                               FILE_ATTRIBUTE_NORMAL,
    5473             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5474             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5475           5 :         if (NT_STATUS_IS_OK(status)) {
    5476           0 :                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
    5477           0 :                 goto fail;
    5478             :         }
    5479             : 
    5480             :         /* This should succeed. */
    5481           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5482             :                              FILE_ATTRIBUTE_NORMAL,
    5483             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5484             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5485           5 :         if (!NT_STATUS_IS_OK(status)) {
    5486           0 :                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
    5487           0 :                 goto fail;
    5488             :         }
    5489             : 
    5490           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5491           5 :         if (!NT_STATUS_IS_OK(status)) {
    5492           0 :                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5493           0 :                 goto fail;
    5494             :         }
    5495             : 
    5496           5 :         status = cli_close(cli1, fnum1);
    5497           5 :         if (!NT_STATUS_IS_OK(status)) {
    5498           0 :                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
    5499           0 :                 goto fail;
    5500             :         }
    5501             : 
    5502           5 :         status = cli_close(cli1, fnum2);
    5503           5 :         if (!NT_STATUS_IS_OK(status)) {
    5504           0 :                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
    5505           0 :                 goto fail;
    5506             :         }
    5507             : 
    5508             :         /* This should fail - file should no longer be there. */
    5509             : 
    5510           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5511           5 :         if (NT_STATUS_IS_OK(status)) {
    5512           0 :                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
    5513           0 :                 status = cli_close(cli1, fnum1);
    5514           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5515           0 :                         printf("[3] close failed (%s)\n", nt_errstr(status));
    5516             :                 }
    5517           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5518           0 :                 goto fail;
    5519             :         }
    5520             : 
    5521           5 :         printf("third delete on close test succeeded.\n");
    5522             : 
    5523             :         /* Test 4 ... */
    5524           5 :         cli_setatr(cli1, fname, 0, 0);
    5525           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5526             : 
    5527           5 :         status = cli_ntcreate(cli1, fname, 0,
    5528             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5529             :                               FILE_ATTRIBUTE_NORMAL,
    5530             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5531             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5532           5 :         if (!NT_STATUS_IS_OK(status)) {
    5533           0 :                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
    5534           0 :                 goto fail;
    5535             :         }
    5536             : 
    5537             :         /* This should succeed. */
    5538           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5539             :                              FILE_ATTRIBUTE_NORMAL,
    5540             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5541             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5542           5 :         if (!NT_STATUS_IS_OK(status)) {
    5543           0 :                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5544           0 :                 goto fail;
    5545             :         }
    5546             : 
    5547           5 :         status = cli_close(cli1, fnum2);
    5548           5 :         if (!NT_STATUS_IS_OK(status)) {
    5549           0 :                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
    5550           0 :                 goto fail;
    5551             :         }
    5552             : 
    5553           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5554           5 :         if (!NT_STATUS_IS_OK(status)) {
    5555           0 :                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5556           0 :                 goto fail;
    5557             :         }
    5558             : 
    5559             :         /* This should fail - no more opens once delete on close set. */
    5560           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5561             :                               FILE_ATTRIBUTE_NORMAL,
    5562             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5563             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5564           5 :         if (NT_STATUS_IS_OK(status)) {
    5565           0 :                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
    5566           0 :                 goto fail;
    5567             :         }
    5568             : 
    5569           5 :         status = cli_close(cli1, fnum1);
    5570           5 :         if (!NT_STATUS_IS_OK(status)) {
    5571           0 :                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
    5572           0 :                 goto fail;
    5573             :         }
    5574             : 
    5575           5 :         printf("fourth delete on close test succeeded.\n");
    5576             : 
    5577             :         /* Test 5 ... */
    5578           5 :         cli_setatr(cli1, fname, 0, 0);
    5579           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5580             : 
    5581           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
    5582           5 :         if (!NT_STATUS_IS_OK(status)) {
    5583           0 :                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
    5584           0 :                 goto fail;
    5585             :         }
    5586             : 
    5587             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5588             : 
    5589           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5590           5 :         if (NT_STATUS_IS_OK(status)) {
    5591           0 :                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
    5592           0 :                 goto fail;
    5593             :         }
    5594             : 
    5595           5 :         status = cli_close(cli1, fnum1);
    5596           5 :         if (!NT_STATUS_IS_OK(status)) {
    5597           0 :                 printf("[5] close failed (%s)\n", nt_errstr(status));
    5598           0 :                 goto fail;
    5599             :         }
    5600             : 
    5601           5 :         printf("fifth delete on close test succeeded.\n");
    5602             : 
    5603             :         /* Test 6 ... */
    5604           5 :         cli_setatr(cli1, fname, 0, 0);
    5605           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5606             : 
    5607           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5608             :                              FILE_ATTRIBUTE_NORMAL,
    5609             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5610             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5611           5 :         if (!NT_STATUS_IS_OK(status)) {
    5612           0 :                 printf("[6] open of %s failed (%s)\n", fname,
    5613             :                        nt_errstr(status));
    5614           0 :                 goto fail;
    5615             :         }
    5616             : 
    5617             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5618             : 
    5619           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5620           5 :         if (NT_STATUS_IS_OK(status)) {
    5621           0 :                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
    5622           0 :                 goto fail;
    5623             :         }
    5624             : 
    5625           5 :         status = cli_close(cli1, fnum1);
    5626           5 :         if (!NT_STATUS_IS_OK(status)) {
    5627           0 :                 printf("[6] close failed (%s)\n", nt_errstr(status));
    5628           0 :                 goto fail;
    5629             :         }
    5630             : 
    5631           5 :         printf("sixth delete on close test succeeded.\n");
    5632             : 
    5633             :         /* Test 7 ... */
    5634           5 :         cli_setatr(cli1, fname, 0, 0);
    5635           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5636             : 
    5637           5 :         status = cli_ntcreate(cli1, fname, 0,
    5638             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5639             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5640             :                               0, 0, &fnum1, NULL);
    5641           5 :         if (!NT_STATUS_IS_OK(status)) {
    5642           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5643           0 :                 goto fail;
    5644             :         }
    5645             : 
    5646           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5647           5 :         if (!NT_STATUS_IS_OK(status)) {
    5648           0 :                 printf("[7] setting delete_on_close on file failed !\n");
    5649           0 :                 goto fail;
    5650             :         }
    5651             : 
    5652           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5653           5 :         if (!NT_STATUS_IS_OK(status)) {
    5654           0 :                 printf("[7] unsetting delete_on_close on file failed !\n");
    5655           0 :                 goto fail;
    5656             :         }
    5657             : 
    5658           5 :         status = cli_close(cli1, fnum1);
    5659           5 :         if (!NT_STATUS_IS_OK(status)) {
    5660           0 :                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
    5661           0 :                 goto fail;
    5662             :         }
    5663             : 
    5664             :         /* This next open should succeed - we reset the flag. */
    5665           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5666           5 :         if (!NT_STATUS_IS_OK(status)) {
    5667           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5668           0 :                 goto fail;
    5669             :         }
    5670             : 
    5671           5 :         status = cli_close(cli1, fnum1);
    5672           5 :         if (!NT_STATUS_IS_OK(status)) {
    5673           0 :                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
    5674           0 :                 goto fail;
    5675             :         }
    5676             : 
    5677           5 :         printf("seventh delete on close test succeeded.\n");
    5678             : 
    5679             :         /* Test 8 ... */
    5680           5 :         cli_setatr(cli1, fname, 0, 0);
    5681           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5682             : 
    5683           5 :         if (!torture_open_connection(&cli2, 1)) {
    5684           0 :                 printf("[8] failed to open second connection.\n");
    5685           0 :                 goto fail;
    5686             :         }
    5687             : 
    5688           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5689             : 
    5690           5 :         status = cli_ntcreate(cli1, fname, 0,
    5691             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5692             :                              FILE_ATTRIBUTE_NORMAL,
    5693             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5694             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5695           5 :         if (!NT_STATUS_IS_OK(status)) {
    5696           0 :                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5697           0 :                 goto fail;
    5698             :         }
    5699             : 
    5700           5 :         status = cli_ntcreate(cli2, fname, 0,
    5701             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5702             :                              FILE_ATTRIBUTE_NORMAL,
    5703             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5704             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5705           5 :         if (!NT_STATUS_IS_OK(status)) {
    5706           0 :                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5707           0 :                 goto fail;
    5708             :         }
    5709             : 
    5710           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5711           5 :         if (!NT_STATUS_IS_OK(status)) {
    5712           0 :                 printf("[8] setting delete_on_close on file failed !\n");
    5713           0 :                 goto fail;
    5714             :         }
    5715             : 
    5716           5 :         status = cli_close(cli1, fnum1);
    5717           5 :         if (!NT_STATUS_IS_OK(status)) {
    5718           0 :                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
    5719           0 :                 goto fail;
    5720             :         }
    5721             : 
    5722           5 :         status = cli_close(cli2, fnum2);
    5723           5 :         if (!NT_STATUS_IS_OK(status)) {
    5724           0 :                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
    5725           0 :                 goto fail;
    5726             :         }
    5727             : 
    5728             :         /* This should fail.. */
    5729           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5730           5 :         if (NT_STATUS_IS_OK(status)) {
    5731           0 :                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
    5732           0 :                 goto fail;
    5733             :         }
    5734             : 
    5735           5 :         printf("eighth delete on close test succeeded.\n");
    5736             : 
    5737             :         /* Test 9 ... */
    5738             : 
    5739             :         /* This should fail - we need to set DELETE_ACCESS. */
    5740           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5741             :                               FILE_ATTRIBUTE_NORMAL,
    5742             :                               FILE_SHARE_NONE,
    5743             :                               FILE_OVERWRITE_IF,
    5744             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5745           5 :         if (NT_STATUS_IS_OK(status)) {
    5746           0 :                 printf("[9] open of %s succeeded should have failed!\n", fname);
    5747           0 :                 goto fail;
    5748             :         }
    5749             : 
    5750           5 :         printf("ninth delete on close test succeeded.\n");
    5751             : 
    5752             :         /* Test 10 ... */
    5753             : 
    5754           5 :         status = cli_ntcreate(cli1, fname, 0,
    5755             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5756             :                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5757             :                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
    5758             :                              0, &fnum1, NULL);
    5759           5 :         if (!NT_STATUS_IS_OK(status)) {
    5760           0 :                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
    5761           0 :                 goto fail;
    5762             :         }
    5763             : 
    5764             :         /* This should delete the file. */
    5765           5 :         status = cli_close(cli1, fnum1);
    5766           5 :         if (!NT_STATUS_IS_OK(status)) {
    5767           0 :                 printf("[10] close failed (%s)\n", nt_errstr(status));
    5768           0 :                 goto fail;
    5769             :         }
    5770             : 
    5771             :         /* This should fail.. */
    5772           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5773           5 :         if (NT_STATUS_IS_OK(status)) {
    5774           0 :                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
    5775           0 :                 goto fail;
    5776             :         }
    5777             : 
    5778           5 :         printf("tenth delete on close test succeeded.\n");
    5779             : 
    5780             :         /* Test 11 ... */
    5781             : 
    5782           5 :         cli_setatr(cli1, fname, 0, 0);
    5783           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5784             : 
    5785             :         /* Can we open a read-only file with delete access? */
    5786             : 
    5787             :         /* Create a readonly file. */
    5788           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5789             :                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
    5790             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5791           5 :         if (!NT_STATUS_IS_OK(status)) {
    5792           0 :                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
    5793           0 :                 goto fail;
    5794             :         }
    5795             : 
    5796           5 :         status = cli_close(cli1, fnum1);
    5797           5 :         if (!NT_STATUS_IS_OK(status)) {
    5798           0 :                 printf("[11] close failed (%s)\n", nt_errstr(status));
    5799           0 :                 goto fail;
    5800             :         }
    5801             : 
    5802             :         /* Now try open for delete access. */
    5803           5 :         status = cli_ntcreate(cli1, fname, 0,
    5804             :                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
    5805             :                              0,
    5806             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5807             :                              FILE_OPEN, 0, 0, &fnum1, NULL);
    5808           5 :         if (!NT_STATUS_IS_OK(status)) {
    5809           0 :                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
    5810           0 :                 goto fail;
    5811             :         }
    5812             : 
    5813           5 :         cli_close(cli1, fnum1);
    5814             : 
    5815           5 :         printf("eleventh delete on close test succeeded.\n");
    5816             : 
    5817             :         /*
    5818             :          * Test 12
    5819             :          * like test 4 but with initial delete on close
    5820             :          */
    5821             : 
    5822           5 :         cli_setatr(cli1, fname, 0, 0);
    5823           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5824             : 
    5825           5 :         status = cli_ntcreate(cli1, fname, 0,
    5826             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5827             :                               FILE_ATTRIBUTE_NORMAL,
    5828             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5829             :                               FILE_OVERWRITE_IF,
    5830             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5831           5 :         if (!NT_STATUS_IS_OK(status)) {
    5832           0 :                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5833           0 :                 goto fail;
    5834             :         }
    5835             : 
    5836           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5837             :                               FILE_ATTRIBUTE_NORMAL,
    5838             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5839             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5840           5 :         if (!NT_STATUS_IS_OK(status)) {
    5841           0 :                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
    5842           0 :                 goto fail;
    5843             :         }
    5844             : 
    5845           5 :         status = cli_close(cli1, fnum2);
    5846           5 :         if (!NT_STATUS_IS_OK(status)) {
    5847           0 :                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
    5848           0 :                 goto fail;
    5849             :         }
    5850             : 
    5851           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5852           5 :         if (!NT_STATUS_IS_OK(status)) {
    5853           0 :                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5854           0 :                 goto fail;
    5855             :         }
    5856             : 
    5857             :         /* This should fail - no more opens once delete on close set. */
    5858           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5859             :                               FILE_ATTRIBUTE_NORMAL,
    5860             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5861             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5862           5 :         if (NT_STATUS_IS_OK(status)) {
    5863           0 :                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
    5864           0 :                 goto fail;
    5865             :         }
    5866             : 
    5867           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5868           5 :         if (!NT_STATUS_IS_OK(status)) {
    5869           0 :                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
    5870           0 :                 goto fail;
    5871             :         }
    5872             : 
    5873           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5874             :                               FILE_ATTRIBUTE_NORMAL,
    5875             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5876             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5877           5 :         if (!NT_STATUS_IS_OK(status)) {
    5878           0 :                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
    5879           0 :                 goto fail;
    5880             :         }
    5881             : 
    5882           5 :         status = cli_close(cli1, fnum2);
    5883           5 :         if (!NT_STATUS_IS_OK(status)) {
    5884           0 :                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
    5885           0 :                 goto fail;
    5886             :         }
    5887             : 
    5888           5 :         status = cli_close(cli1, fnum1);
    5889           5 :         if (!NT_STATUS_IS_OK(status)) {
    5890           0 :                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
    5891           0 :                 goto fail;
    5892             :         }
    5893             : 
    5894             :         /*
    5895             :          * setting delete on close on the handle does
    5896             :          * not unset the initial delete on close...
    5897             :          */
    5898           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5899             :                               FILE_ATTRIBUTE_NORMAL,
    5900             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5901             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5902           5 :         if (NT_STATUS_IS_OK(status)) {
    5903           0 :                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
    5904           0 :                 goto fail;
    5905           5 :         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5906           0 :                 printf("ntcreate returned %s, expected "
    5907             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
    5908             :                        nt_errstr(status));
    5909           0 :                 goto fail;
    5910             :         }
    5911             : 
    5912           5 :         printf("twelfth delete on close test succeeded.\n");
    5913             : 
    5914             : 
    5915           5 :         printf("finished delete test\n");
    5916             : 
    5917           5 :         correct = true;
    5918             : 
    5919           5 :   fail:
    5920             :         /* FIXME: This will crash if we aborted before cli2 got
    5921             :          * initialized, because these functions don't handle
    5922             :          * uninitialized connections. */
    5923             : 
    5924           5 :         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
    5925           5 :         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
    5926           5 :         cli_setatr(cli1, fname, 0, 0);
    5927           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5928             : 
    5929           5 :         if (cli1 && !torture_close_connection(cli1)) {
    5930           0 :                 correct = False;
    5931             :         }
    5932           5 :         if (cli2 && !torture_close_connection(cli2)) {
    5933           0 :                 correct = False;
    5934             :         }
    5935           5 :         return correct;
    5936             : }
    5937             : 
    5938             : struct delete_stream_state {
    5939             :         bool closed;
    5940             : };
    5941             : 
    5942             : static void delete_stream_unlinked(struct tevent_req *subreq);
    5943             : static void delete_stream_closed(struct tevent_req *subreq);
    5944             : 
    5945           5 : static struct tevent_req *delete_stream_send(
    5946             :         TALLOC_CTX *mem_ctx,
    5947             :         struct tevent_context *ev,
    5948             :         struct cli_state *cli,
    5949             :         const char *base_fname,
    5950             :         uint16_t stream_fnum)
    5951             : {
    5952           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    5953           5 :         struct delete_stream_state *state = NULL;
    5954             : 
    5955           5 :         req = tevent_req_create(
    5956             :                 mem_ctx, &state, struct delete_stream_state);
    5957           5 :         if (req == NULL) {
    5958           0 :                 return NULL;
    5959             :         }
    5960             : 
    5961           5 :         subreq = cli_unlink_send(
    5962             :                 state,
    5963             :                 ev,
    5964             :                 cli,
    5965             :                 base_fname,
    5966             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5967           5 :         if (tevent_req_nomem(subreq, req)) {
    5968           0 :                 return tevent_req_post(req, ev);
    5969             :         }
    5970           5 :         tevent_req_set_callback(subreq, delete_stream_unlinked, req);
    5971             : 
    5972           5 :         subreq = cli_close_send(state, ev, cli, stream_fnum, 0);
    5973           5 :         if (tevent_req_nomem(subreq, req)) {
    5974           0 :                 return tevent_req_post(req, ev);
    5975             :         }
    5976           5 :         tevent_req_set_callback(subreq, delete_stream_closed, req);
    5977             : 
    5978           5 :         return req;
    5979             : }
    5980             : 
    5981           5 : static void delete_stream_unlinked(struct tevent_req *subreq)
    5982             : {
    5983           5 :         struct tevent_req *req = tevent_req_callback_data(
    5984             :                 subreq, struct tevent_req);
    5985           5 :         struct delete_stream_state *state = tevent_req_data(
    5986             :                 req, struct delete_stream_state);
    5987           0 :         NTSTATUS status;
    5988             : 
    5989           5 :         status = cli_unlink_recv(subreq);
    5990           5 :         TALLOC_FREE(subreq);
    5991           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    5992           0 :                 printf("cli_unlink returned %s\n",
    5993             :                        nt_errstr(status));
    5994           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5995           0 :                 return;
    5996             :         }
    5997           5 :         if (!state->closed) {
    5998             :                 /* close reply should have come in first */
    5999           0 :                 printf("Not closed\n");
    6000           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    6001           0 :                 return;
    6002             :         }
    6003           5 :         tevent_req_done(req);
    6004             : }
    6005             : 
    6006           5 : static void delete_stream_closed(struct tevent_req *subreq)
    6007             : {
    6008           5 :         struct tevent_req *req = tevent_req_callback_data(
    6009             :                 subreq, struct tevent_req);
    6010           5 :         struct delete_stream_state *state = tevent_req_data(
    6011             :                 req, struct delete_stream_state);
    6012           0 :         NTSTATUS status;
    6013             : 
    6014           5 :         status = cli_close_recv(subreq);
    6015           5 :         TALLOC_FREE(subreq);
    6016           5 :         if (tevent_req_nterror(req, status)) {
    6017           0 :                 return;
    6018             :         }
    6019             :         /* also waiting for the unlink to come back */
    6020           5 :         state->closed = true;
    6021             : }
    6022             : 
    6023           5 : static NTSTATUS delete_stream_recv(struct tevent_req *req)
    6024             : {
    6025           5 :         return tevent_req_simple_recv_ntstatus(req);
    6026             : }
    6027             : 
    6028           5 : static bool run_delete_stream(int dummy)
    6029             : {
    6030           5 :         struct tevent_context *ev = NULL;
    6031           5 :         struct tevent_req *req = NULL;
    6032           5 :         struct cli_state *cli = NULL;
    6033           5 :         const char fname[] = "delete_stream";
    6034           5 :         const char fname_stream[] = "delete_stream:Zone.Identifier:$DATA";
    6035           0 :         uint16_t fnum1, fnum2;
    6036           0 :         NTSTATUS status;
    6037           0 :         bool ok;
    6038             : 
    6039           5 :         printf("Starting stream delete test\n");
    6040             : 
    6041           5 :         ok = torture_open_connection(&cli, 0);
    6042           5 :         if (!ok) {
    6043           0 :                 return false;
    6044             :         }
    6045             : 
    6046           5 :         cli_setatr(cli, fname, 0, 0);
    6047           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6048             : 
    6049             :         /* Create the file. */
    6050           5 :         status = cli_ntcreate(
    6051             :                 cli,
    6052             :                 fname,
    6053             :                 0,
    6054             :                 READ_CONTROL_ACCESS,
    6055             :                 0,
    6056             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6057             :                 FILE_CREATE,
    6058             :                 0x0,
    6059             :                 0x0,
    6060             :                 &fnum1,
    6061             :                 NULL);
    6062           5 :         if (!NT_STATUS_IS_OK(status)) {
    6063           0 :                 d_fprintf(stderr,
    6064             :                           "cli_ntcreate of %s failed (%s)\n",
    6065             :                           fname,
    6066             :                           nt_errstr(status));
    6067           0 :                 return false;
    6068             :         }
    6069           5 :         status = cli_close(cli, fnum1);
    6070           5 :         if (!NT_STATUS_IS_OK(status)) {
    6071           0 :                 d_fprintf(stderr,
    6072             :                           "cli_close of %s failed (%s)\n",
    6073             :                           fname,
    6074             :                           nt_errstr(status));
    6075           0 :                 return false;
    6076             :         }
    6077             : 
    6078             :         /* Now create the stream. */
    6079           5 :         status = cli_ntcreate(
    6080             :                 cli,
    6081             :                 fname_stream,
    6082             :                 0,
    6083             :                 FILE_WRITE_DATA,
    6084             :                 0,
    6085             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6086             :                 FILE_CREATE,
    6087             :                 0x0,
    6088             :                 0x0,
    6089             :                 &fnum1,
    6090             :                 NULL);
    6091             : 
    6092           5 :         if (!NT_STATUS_IS_OK(status)) {
    6093           0 :                 d_fprintf(stderr,
    6094             :                           "cli_ntcreate of %s failed (%s)\n",
    6095             :                           fname_stream,
    6096             :                           nt_errstr(status));
    6097           0 :                 return false;
    6098             :         }
    6099             : 
    6100             :         /* open it a second time */
    6101             : 
    6102           5 :         status = cli_ntcreate(
    6103             :                 cli,
    6104             :                 fname_stream,
    6105             :                 0,
    6106             :                 FILE_WRITE_DATA,
    6107             :                 0,
    6108             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6109             :                 FILE_OPEN,
    6110             :                 0x0,
    6111             :                 0x0,
    6112             :                 &fnum2,
    6113             :                 NULL);
    6114             : 
    6115           5 :         if (!NT_STATUS_IS_OK(status)) {
    6116           0 :                 d_fprintf(stderr,
    6117             :                           "2nd cli_ntcreate of %s failed (%s)\n",
    6118             :                           fname_stream,
    6119             :                           nt_errstr(status));
    6120           0 :                 return false;
    6121             :         }
    6122             : 
    6123           5 :         ev = samba_tevent_context_init(talloc_tos());
    6124           5 :         if (ev == NULL) {
    6125           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    6126           0 :                 return false;
    6127             :         }
    6128             : 
    6129           5 :         req = delete_stream_send(ev, ev, cli, fname, fnum1);
    6130           5 :         if (req == NULL) {
    6131           0 :                 d_fprintf(stderr, "delete_stream_send failed\n");
    6132           0 :                 return false;
    6133             :         }
    6134             : 
    6135           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    6136           5 :         if (!ok) {
    6137           0 :                 d_fprintf(stderr,
    6138             :                           "tevent_req_poll_ntstatus failed: %s\n",
    6139             :                           nt_errstr(status));
    6140           0 :                 return false;
    6141             :         }
    6142             : 
    6143           5 :         status = delete_stream_recv(req);
    6144           5 :         TALLOC_FREE(req);
    6145           5 :         if (!NT_STATUS_IS_OK(status)) {
    6146           0 :                 d_fprintf(stderr,
    6147             :                           "delete_stream failed: %s\n",
    6148             :                           nt_errstr(status));
    6149           0 :                 return false;
    6150             :         }
    6151             : 
    6152           5 :         status = cli_close(cli, fnum2);
    6153           5 :         if (!NT_STATUS_IS_OK(status)) {
    6154           0 :                 d_fprintf(stderr,
    6155             :                           "close failed: %s\n",
    6156             :                           nt_errstr(status));
    6157           0 :                 return false;
    6158             :         }
    6159             : 
    6160           5 :         status = cli_unlink(
    6161             :                 cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6162           5 :         if (!NT_STATUS_IS_OK(status)) {
    6163           0 :                 d_fprintf(stderr,
    6164             :                           "unlink failed: %s\n",
    6165             :                           nt_errstr(status));
    6166           0 :                 return false;
    6167             :         }
    6168             : 
    6169           5 :         return true;
    6170             : }
    6171             : 
    6172             : /*
    6173             :   Exercise delete on close semantics - use on the PRINT1 share in torture
    6174             :   testing.
    6175             :  */
    6176           2 : static bool run_delete_print_test(int dummy)
    6177             : {
    6178           2 :         struct cli_state *cli1 = NULL;
    6179           2 :         const char *fname = "print_delete.file";
    6180           2 :         uint16_t fnum1 = (uint16_t)-1;
    6181           2 :         bool correct = false;
    6182           2 :         const char *buf = "print file data\n";
    6183           0 :         NTSTATUS status;
    6184             : 
    6185           2 :         printf("starting print delete test\n");
    6186             : 
    6187           2 :         if (!torture_open_connection(&cli1, 0)) {
    6188           0 :                 return false;
    6189             :         }
    6190             : 
    6191           2 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    6192             : 
    6193           2 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    6194             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    6195             :                               0, 0, &fnum1, NULL);
    6196           2 :         if (!NT_STATUS_IS_OK(status)) {
    6197           0 :                 printf("open of %s failed (%s)\n",
    6198             :                         fname,
    6199             :                         nt_errstr(status));
    6200           0 :                 goto fail;
    6201             :         }
    6202             : 
    6203           2 :         status = cli_writeall(cli1,
    6204             :                         fnum1,
    6205             :                         0,
    6206             :                         (const uint8_t *)buf,
    6207             :                         0, /* offset */
    6208             :                         strlen(buf), /* size */
    6209             :                         NULL);
    6210           2 :         if (!NT_STATUS_IS_OK(status)) {
    6211           0 :                 printf("writing print file data failed (%s)\n",
    6212             :                         nt_errstr(status));
    6213           0 :                 goto fail;
    6214             :         }
    6215             : 
    6216           2 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    6217           2 :         if (!NT_STATUS_IS_OK(status)) {
    6218           0 :                 printf("setting delete_on_close failed (%s)\n",
    6219             :                         nt_errstr(status));
    6220           0 :                 goto fail;
    6221             :         }
    6222             : 
    6223           2 :         status = cli_close(cli1, fnum1);
    6224           2 :         if (!NT_STATUS_IS_OK(status)) {
    6225           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    6226           0 :                 goto fail;
    6227             :         }
    6228             : 
    6229           2 :         printf("finished print delete test\n");
    6230             : 
    6231           2 :         correct = true;
    6232             : 
    6233           2 :   fail:
    6234             : 
    6235           2 :         if (fnum1 != (uint16_t)-1) {
    6236           2 :                 cli_close(cli1, fnum1);
    6237             :         }
    6238             : 
    6239           2 :         if (cli1 && !torture_close_connection(cli1)) {
    6240           0 :                 correct = false;
    6241             :         }
    6242           2 :         return correct;
    6243             : }
    6244             : 
    6245           4 : static bool run_deletetest_ln(int dummy)
    6246             : {
    6247           0 :         struct cli_state *cli;
    6248           4 :         const char *fname = "\\delete1";
    6249           4 :         const char *fname_ln = "\\delete1_ln";
    6250           0 :         uint16_t fnum;
    6251           0 :         uint16_t fnum1;
    6252           0 :         NTSTATUS status;
    6253           4 :         bool correct = true;
    6254           0 :         time_t t;
    6255             : 
    6256           4 :         printf("starting deletetest-ln\n");
    6257             : 
    6258           4 :         if (!torture_open_connection(&cli, 0)) {
    6259           0 :                 return false;
    6260             :         }
    6261             : 
    6262           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6263           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6264             : 
    6265           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6266             : 
    6267             :         /* Create the file. */
    6268           4 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6269           4 :         if (!NT_STATUS_IS_OK(status)) {
    6270           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    6271           0 :                 return false;
    6272             :         }
    6273             : 
    6274           4 :         status = cli_close(cli, fnum);
    6275           4 :         if (!NT_STATUS_IS_OK(status)) {
    6276           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    6277           0 :                 return false;
    6278             :         }
    6279             : 
    6280             :         /* Now create a hardlink. */
    6281           4 :         status = cli_hardlink(cli, fname, fname_ln);
    6282           4 :         if (!NT_STATUS_IS_OK(status)) {
    6283           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    6284           0 :                 return false;
    6285             :         }
    6286             : 
    6287             :         /* Open the original file. */
    6288           4 :         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
    6289             :                         FILE_ATTRIBUTE_NORMAL,
    6290             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6291             :                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
    6292           4 :         if (!NT_STATUS_IS_OK(status)) {
    6293           0 :                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
    6294           0 :                 return false;
    6295             :         }
    6296             : 
    6297             :         /* Unlink the hard link path. */
    6298           4 :         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
    6299             :                         FILE_ATTRIBUTE_NORMAL,
    6300             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6301             :                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
    6302           4 :         if (!NT_STATUS_IS_OK(status)) {
    6303           0 :                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
    6304           0 :                 return false;
    6305             :         }
    6306           4 :         status = cli_nt_delete_on_close(cli, fnum1, true);
    6307           4 :         if (!NT_STATUS_IS_OK(status)) {
    6308           0 :                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
    6309             :                         __location__, fname_ln, nt_errstr(status));
    6310           0 :                 return false;
    6311             :         }
    6312             : 
    6313           4 :         status = cli_close(cli, fnum1);
    6314           4 :         if (!NT_STATUS_IS_OK(status)) {
    6315           0 :                 printf("close %s failed (%s)\n",
    6316             :                         fname_ln, nt_errstr(status));
    6317           0 :                 return false;
    6318             :         }
    6319             : 
    6320           4 :         status = cli_close(cli, fnum);
    6321           4 :         if (!NT_STATUS_IS_OK(status)) {
    6322           0 :                 printf("close %s failed (%s)\n",
    6323             :                         fname, nt_errstr(status));
    6324           0 :                 return false;
    6325             :         }
    6326             : 
    6327             :         /* Ensure the original file is still there. */
    6328           4 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    6329           4 :         if (!NT_STATUS_IS_OK(status)) {
    6330           0 :                 printf("%s getatr on file %s failed (%s)\n",
    6331             :                         __location__,
    6332             :                         fname,
    6333             :                         nt_errstr(status));
    6334           0 :                 correct = False;
    6335             :         }
    6336             : 
    6337             :         /* Ensure the link path is gone. */
    6338           4 :         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
    6339           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    6340           0 :                 printf("%s, getatr for file %s returned wrong error code %s "
    6341             :                         "- should have been deleted\n",
    6342             :                         __location__,
    6343             :                         fname_ln, nt_errstr(status));
    6344           0 :                 correct = False;
    6345             :         }
    6346             : 
    6347           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6348           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6349             : 
    6350           4 :         if (!torture_close_connection(cli)) {
    6351           0 :                 correct = false;
    6352             :         }
    6353             : 
    6354           4 :         printf("finished deletetest-ln\n");
    6355             : 
    6356           4 :         return correct;
    6357             : }
    6358             : 
    6359             : /*
    6360             :   print out server properties
    6361             :  */
    6362           5 : static bool run_properties(int dummy)
    6363             : {
    6364           0 :         struct cli_state *cli;
    6365           5 :         bool correct = True;
    6366             : 
    6367           5 :         printf("starting properties test\n");
    6368             : 
    6369           5 :         ZERO_STRUCT(cli);
    6370             : 
    6371           5 :         if (!torture_open_connection(&cli, 0)) {
    6372           0 :                 return False;
    6373             :         }
    6374             : 
    6375           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6376             : 
    6377           5 :         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
    6378             : 
    6379           5 :         if (!torture_close_connection(cli)) {
    6380           0 :                 correct = False;
    6381             :         }
    6382             : 
    6383           5 :         return correct;
    6384             : }
    6385             : 
    6386             : 
    6387             : 
    6388             : /* FIRST_DESIRED_ACCESS   0xf019f */
    6389             : #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
    6390             :                                FILE_READ_EA|                           /* 0xf */ \
    6391             :                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
    6392             :                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
    6393             :                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
    6394             :                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
    6395             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    6396             : #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6397             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6398             :                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
    6399             : 
    6400             : #if 0
    6401             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6402             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6403             :                                FILE_READ_DATA|\
    6404             :                                WRITE_OWNER_ACCESS                      /* */
    6405             : #endif
    6406             : 
    6407             : /*
    6408             :   Test ntcreate calls made by xcopy
    6409             :  */
    6410           5 : static bool run_xcopy(int dummy)
    6411             : {
    6412           0 :         static struct cli_state *cli1;
    6413           5 :         const char *fname = "\\test.txt";
    6414           5 :         bool correct = True;
    6415           0 :         uint16_t fnum1, fnum2;
    6416           0 :         NTSTATUS status;
    6417             : 
    6418           5 :         printf("starting xcopy test\n");
    6419             : 
    6420           5 :         if (!torture_open_connection(&cli1, 0)) {
    6421           0 :                 return False;
    6422             :         }
    6423             : 
    6424           5 :         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
    6425             :                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
    6426             :                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
    6427           5 :         if (!NT_STATUS_IS_OK(status)) {
    6428           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6429           0 :                 return False;
    6430             :         }
    6431             : 
    6432           5 :         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
    6433             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6434             :                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
    6435           5 :         if (!NT_STATUS_IS_OK(status)) {
    6436           0 :                 printf("second open failed - %s\n", nt_errstr(status));
    6437           0 :                 return False;
    6438             :         }
    6439             : 
    6440           5 :         if (!torture_close_connection(cli1)) {
    6441           0 :                 correct = False;
    6442             :         }
    6443             : 
    6444           5 :         return correct;
    6445             : }
    6446             : 
    6447             : /*
    6448             :   Test rename on files open with share delete and no share delete.
    6449             :  */
    6450           5 : static bool run_rename(int dummy)
    6451             : {
    6452           0 :         static struct cli_state *cli1;
    6453           5 :         const char *fname = "\\test.txt";
    6454           5 :         const char *fname1 = "\\test1.txt";
    6455           5 :         bool correct = True;
    6456           0 :         uint16_t fnum1;
    6457           0 :         uint32_t attr;
    6458           0 :         NTSTATUS status;
    6459             : 
    6460           5 :         printf("starting rename test\n");
    6461             : 
    6462           5 :         if (!torture_open_connection(&cli1, 0)) {
    6463           0 :                 return False;
    6464             :         }
    6465             : 
    6466           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6467           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6468             : 
    6469           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6470             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    6471             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6472           5 :         if (!NT_STATUS_IS_OK(status)) {
    6473           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6474           0 :                 return False;
    6475             :         }
    6476             : 
    6477           5 :         status = cli_rename(cli1, fname, fname1, false);
    6478           5 :         if (!NT_STATUS_IS_OK(status)) {
    6479           5 :                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
    6480             :         } else {
    6481           0 :                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
    6482           0 :                 correct = False;
    6483             :         }
    6484             : 
    6485           5 :         status = cli_close(cli1, fnum1);
    6486           5 :         if (!NT_STATUS_IS_OK(status)) {
    6487           0 :                 printf("close - 1 failed (%s)\n", nt_errstr(status));
    6488           0 :                 return False;
    6489             :         }
    6490             : 
    6491           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6492           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6493           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
    6494             : #if 0
    6495             :                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
    6496             : #else
    6497             :                               FILE_SHARE_DELETE|FILE_SHARE_READ,
    6498             : #endif
    6499             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6500           5 :         if (!NT_STATUS_IS_OK(status)) {
    6501           0 :                 printf("Second open failed - %s\n", nt_errstr(status));
    6502           0 :                 return False;
    6503             :         }
    6504             : 
    6505           5 :         status = cli_rename(cli1, fname, fname1, false);
    6506           5 :         if (!NT_STATUS_IS_OK(status)) {
    6507           0 :                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
    6508           0 :                 correct = False;
    6509             :         } else {
    6510           5 :                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
    6511             :         }
    6512             : 
    6513           5 :         status = cli_close(cli1, fnum1);
    6514           5 :         if (!NT_STATUS_IS_OK(status)) {
    6515           0 :                 printf("close - 2 failed (%s)\n", nt_errstr(status));
    6516           0 :                 return False;
    6517             :         }
    6518             : 
    6519           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6520           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6521             : 
    6522           5 :         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
    6523             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    6524             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6525           5 :         if (!NT_STATUS_IS_OK(status)) {
    6526           0 :                 printf("Third open failed - %s\n", nt_errstr(status));
    6527           0 :                 return False;
    6528             :         }
    6529             : 
    6530             : 
    6531           5 :         status = cli_rename(cli1, fname, fname1, false);
    6532           5 :         if (!NT_STATUS_IS_OK(status)) {
    6533           0 :                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
    6534           0 :                 correct = False;
    6535             :         } else {
    6536           5 :                 printf("Third rename succeeded (SHARE_NONE)\n");
    6537             :         }
    6538             : 
    6539           5 :         status = cli_close(cli1, fnum1);
    6540           5 :         if (!NT_STATUS_IS_OK(status)) {
    6541           0 :                 printf("close - 3 failed (%s)\n", nt_errstr(status));
    6542           0 :                 return False;
    6543             :         }
    6544             : 
    6545           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6546           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6547             : 
    6548             :         /*----*/
    6549             : 
    6550           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6551             :                               FILE_ATTRIBUTE_NORMAL,
    6552             :                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    6553             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6554           5 :         if (!NT_STATUS_IS_OK(status)) {
    6555           0 :                 printf("Fourth open failed - %s\n", nt_errstr(status));
    6556           0 :                 return False;
    6557             :         }
    6558             : 
    6559           5 :         status = cli_rename(cli1, fname, fname1, false);
    6560           5 :         if (!NT_STATUS_IS_OK(status)) {
    6561           5 :                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
    6562             :         } else {
    6563           0 :                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
    6564           0 :                 correct = False;
    6565             :         }
    6566             : 
    6567           5 :         status = cli_close(cli1, fnum1);
    6568           5 :         if (!NT_STATUS_IS_OK(status)) {
    6569           0 :                 printf("close - 4 failed (%s)\n", nt_errstr(status));
    6570           0 :                 return False;
    6571             :         }
    6572             : 
    6573           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6574           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6575             : 
    6576             :         /*--*/
    6577             : 
    6578           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6579             :                          FILE_ATTRIBUTE_NORMAL,
    6580             :                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    6581             :                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6582           5 :         if (!NT_STATUS_IS_OK(status)) {
    6583           0 :                 printf("Fifth open failed - %s\n", nt_errstr(status));
    6584           0 :                 return False;
    6585             :         }
    6586             : 
    6587           5 :         status = cli_rename(cli1, fname, fname1, false);
    6588           5 :         if (!NT_STATUS_IS_OK(status)) {
    6589           0 :                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
    6590           0 :                 correct = False;
    6591             :         } else {
    6592           5 :                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
    6593             :         }
    6594             : 
    6595             :         /*--*/
    6596           5 :         status = cli_close(cli1, fnum1);
    6597           5 :         if (!NT_STATUS_IS_OK(status)) {
    6598           0 :                 printf("close - 5 failed (%s)\n", nt_errstr(status));
    6599           0 :                 return False;
    6600             :         }
    6601             : 
    6602             :         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
    6603           5 :         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
    6604           5 :         if (!NT_STATUS_IS_OK(status)) {
    6605           0 :                 printf("getatr on file %s failed - %s ! \n",
    6606             :                         fname1, nt_errstr(status));
    6607           0 :                 correct = False;
    6608             :         } else {
    6609           5 :                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
    6610           0 :                         printf("Renamed file %s has wrong attr 0x%x "
    6611             :                                 "(should be 0x%x)\n",
    6612             :                                 fname1,
    6613             :                                 attr,
    6614             :                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
    6615           0 :                         correct = False;
    6616             :                 } else {
    6617           5 :                         printf("Renamed file %s has archive bit set\n", fname1);
    6618             :                 }
    6619             :         }
    6620             : 
    6621           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6622           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6623             : 
    6624           5 :         if (!torture_close_connection(cli1)) {
    6625           0 :                 correct = False;
    6626             :         }
    6627             : 
    6628           5 :         return correct;
    6629             : }
    6630             : 
    6631             : /*
    6632             :   Test rename into a directory with an ACL denying it.
    6633             :  */
    6634           4 : static bool run_rename_access(int dummy)
    6635             : {
    6636           0 :         static struct cli_state *cli = NULL;
    6637           0 :         static struct cli_state *posix_cli = NULL;
    6638           4 :         const char *src = "test.txt";
    6639           4 :         const char *dname = "dir";
    6640           4 :         const char *dst = "dir\\test.txt";
    6641           4 :         const char *dsrc = "test.dir";
    6642           4 :         const char *ddst = "dir\\test.dir";
    6643           4 :         uint16_t fnum = (uint16_t)-1;
    6644           4 :         struct security_descriptor *sd = NULL;
    6645           4 :         struct security_descriptor *newsd = NULL;
    6646           0 :         NTSTATUS status;
    6647           4 :         TALLOC_CTX *frame = NULL;
    6648             : 
    6649           4 :         frame = talloc_stackframe();
    6650           4 :         printf("starting rename access test\n");
    6651             : 
    6652             :         /* Windows connection. */
    6653           4 :         if (!torture_open_connection(&cli, 0)) {
    6654           0 :                 goto fail;
    6655             :         }
    6656             : 
    6657           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6658             : 
    6659             :         /* Posix connection. */
    6660           4 :         if (!torture_open_connection(&posix_cli, 0)) {
    6661           0 :                 goto fail;
    6662             :         }
    6663             : 
    6664           4 :         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
    6665             : 
    6666           4 :         status = torture_setup_unix_extensions(posix_cli);
    6667           4 :         if (!NT_STATUS_IS_OK(status)) {
    6668           0 :                 goto fail;
    6669             :         }
    6670             : 
    6671             :         /* Start with a clean slate. */
    6672           4 :         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6673           4 :         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6674           4 :         cli_rmdir(cli, dsrc);
    6675           4 :         cli_rmdir(cli, ddst);
    6676           4 :         cli_rmdir(cli, dname);
    6677             : 
    6678             :         /*
    6679             :          * Setup the destination directory with a DENY ACE to
    6680             :          * prevent new files within it.
    6681             :          */
    6682           4 :         status = cli_ntcreate(cli,
    6683             :                                 dname,
    6684             :                                 0,
    6685             :                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
    6686             :                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
    6687             :                                         WRITE_OWNER_ACCESS,
    6688             :                                 FILE_ATTRIBUTE_DIRECTORY,
    6689             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6690             :                                 FILE_CREATE,
    6691             :                                 FILE_DIRECTORY_FILE,
    6692             :                                 0,
    6693             :                                 &fnum,
    6694             :                                 NULL);
    6695           4 :         if (!NT_STATUS_IS_OK(status)) {
    6696           0 :                 printf("Create of %s - %s\n", dname, nt_errstr(status));
    6697           0 :                 goto fail;
    6698             :         }
    6699             : 
    6700           4 :         status = cli_query_secdesc(cli,
    6701             :                                 fnum,
    6702             :                                 frame,
    6703             :                                 &sd);
    6704           4 :         if (!NT_STATUS_IS_OK(status)) {
    6705           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6706             :                         dname, nt_errstr(status));
    6707           0 :                 goto fail;
    6708             :         }
    6709             : 
    6710           4 :         newsd = security_descriptor_dacl_create(frame,
    6711             :                                         0,
    6712             :                                         NULL,
    6713             :                                         NULL,
    6714             :                                         SID_WORLD,
    6715             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6716             :                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
    6717             :                                         0,
    6718             :                                         NULL);
    6719           4 :         if (newsd == NULL) {
    6720           0 :                 goto fail;
    6721             :         }
    6722           8 :         sd->dacl = security_acl_concatenate(frame,
    6723           4 :                                         newsd->dacl,
    6724           4 :                                         sd->dacl);
    6725           4 :         if (sd->dacl == NULL) {
    6726           0 :                 goto fail;
    6727             :         }
    6728           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6729           4 :         if (!NT_STATUS_IS_OK(status)) {
    6730           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6731             :                         dname, nt_errstr(status));
    6732           0 :                 goto fail;
    6733             :         }
    6734           4 :         status = cli_close(cli, fnum);
    6735           4 :         if (!NT_STATUS_IS_OK(status)) {
    6736           0 :                 printf("close failed for %s (%s)\n",
    6737             :                         dname, nt_errstr(status));
    6738           0 :                 goto fail;
    6739             :         }
    6740             :         /* Now go around the back and chmod to 777 via POSIX. */
    6741           4 :         status = cli_posix_chmod(posix_cli, dname, 0777);
    6742           4 :         if (!NT_STATUS_IS_OK(status)) {
    6743           0 :                 printf("cli_posix_chmod failed for %s (%s)\n",
    6744             :                         dname, nt_errstr(status));
    6745           0 :                 goto fail;
    6746             :         }
    6747             : 
    6748             :         /* Check we can't create a file within dname via Windows. */
    6749           4 :         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6750           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6751           0 :                 cli_close(posix_cli, fnum);
    6752           0 :                 printf("Create of %s should be ACCESS denied, was %s\n",
    6753             :                         dst, nt_errstr(status));
    6754           0 :                 goto fail;
    6755             :         }
    6756             : 
    6757             :         /* Make the sample file/directory. */
    6758           4 :         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6759           4 :         if (!NT_STATUS_IS_OK(status)) {
    6760           0 :                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
    6761           0 :                 goto fail;
    6762             :         }
    6763           4 :         status = cli_close(cli, fnum);
    6764           4 :         if (!NT_STATUS_IS_OK(status)) {
    6765           0 :                 printf("cli_close failed (%s)\n", nt_errstr(status));
    6766           0 :                 goto fail;
    6767             :         }
    6768             : 
    6769           4 :         status = cli_mkdir(cli, dsrc);
    6770           4 :         if (!NT_STATUS_IS_OK(status)) {
    6771           0 :                 printf("cli_mkdir of %s failed (%s)\n",
    6772             :                         dsrc, nt_errstr(status));
    6773           0 :                 goto fail;
    6774             :         }
    6775             : 
    6776             :         /*
    6777             :          * OK - renames of the new file and directory into the
    6778             :          * dst directory should fail.
    6779             :          */
    6780             : 
    6781           4 :         status = cli_rename(cli, src, dst, false);
    6782           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6783           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6784             :                         src, dst, nt_errstr(status));
    6785           0 :                 goto fail;
    6786             :         }
    6787           4 :         status = cli_rename(cli, dsrc, ddst, false);
    6788           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6789           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6790             :                         src, dst, nt_errstr(status));
    6791           0 :                 goto fail;
    6792             :         }
    6793             : 
    6794           4 :         TALLOC_FREE(frame);
    6795           4 :         return true;
    6796             : 
    6797           0 :   fail:
    6798             : 
    6799           0 :         if (posix_cli) {
    6800           0 :                 torture_close_connection(posix_cli);
    6801             :         }
    6802             : 
    6803           0 :         if (cli) {
    6804           0 :                 if (fnum != (uint16_t)-1) {
    6805           0 :                         cli_close(cli, fnum);
    6806             :                 }
    6807           0 :                 cli_unlink(cli, src,
    6808             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6809           0 :                 cli_unlink(cli, dst,
    6810             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6811           0 :                 cli_rmdir(cli, dsrc);
    6812           0 :                 cli_rmdir(cli, ddst);
    6813           0 :                 cli_rmdir(cli, dname);
    6814             : 
    6815           0 :                 torture_close_connection(cli);
    6816             :         }
    6817             : 
    6818           0 :         TALLOC_FREE(frame);
    6819           0 :         return false;
    6820             : }
    6821             : 
    6822             : /*
    6823             :   Test owner rights ACE.
    6824             :  */
    6825           4 : static bool run_owner_rights(int dummy)
    6826             : {
    6827           0 :         static struct cli_state *cli = NULL;
    6828           4 :         const char *fname = "owner_rights.txt";
    6829           4 :         uint16_t fnum = (uint16_t)-1;
    6830           4 :         struct security_descriptor *sd = NULL;
    6831           4 :         struct security_descriptor *newsd = NULL;
    6832           0 :         NTSTATUS status;
    6833           4 :         TALLOC_CTX *frame = NULL;
    6834             : 
    6835           4 :         frame = talloc_stackframe();
    6836           4 :         printf("starting owner rights test\n");
    6837             : 
    6838             :         /* Windows connection. */
    6839           4 :         if (!torture_open_connection(&cli, 0)) {
    6840           0 :                 goto fail;
    6841             :         }
    6842             : 
    6843           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6844             : 
    6845             :         /* Start with a clean slate. */
    6846           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6847             : 
    6848             :         /* Create the test file. */
    6849             :         /* Now try and open for read and write-dac. */
    6850           4 :         status = cli_ntcreate(cli,
    6851             :                                 fname,
    6852             :                                 0,
    6853             :                                 GENERIC_ALL_ACCESS,
    6854             :                                 FILE_ATTRIBUTE_NORMAL,
    6855             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6856             :                                         FILE_SHARE_DELETE,
    6857             :                                 FILE_CREATE,
    6858             :                                 0,
    6859             :                                 0,
    6860             :                                 &fnum,
    6861             :                                 NULL);
    6862           4 :         if (!NT_STATUS_IS_OK(status)) {
    6863           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6864           0 :                 goto fail;
    6865             :         }
    6866             : 
    6867             :         /* Get the original SD. */
    6868           4 :         status = cli_query_secdesc(cli,
    6869             :                                 fnum,
    6870             :                                 frame,
    6871             :                                 &sd);
    6872           4 :         if (!NT_STATUS_IS_OK(status)) {
    6873           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6874             :                         fname, nt_errstr(status));
    6875           0 :                 goto fail;
    6876             :         }
    6877             : 
    6878             :         /*
    6879             :          * Add an "owner-rights" ACE denying WRITE_DATA,
    6880             :          * and an "owner-rights" ACE allowing READ_DATA.
    6881             :          */
    6882             : 
    6883           4 :         newsd = security_descriptor_dacl_create(frame,
    6884             :                                         0,
    6885             :                                         NULL,
    6886             :                                         NULL,
    6887             :                                         SID_OWNER_RIGHTS,
    6888             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6889             :                                         FILE_WRITE_DATA,
    6890             :                                         0,
    6891             :                                         SID_OWNER_RIGHTS,
    6892             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6893             :                                         FILE_READ_DATA,
    6894             :                                         0,
    6895             :                                         NULL);
    6896           4 :         if (newsd == NULL) {
    6897           0 :                 goto fail;
    6898             :         }
    6899           8 :         sd->dacl = security_acl_concatenate(frame,
    6900           4 :                                         newsd->dacl,
    6901           4 :                                         sd->dacl);
    6902           4 :         if (sd->dacl == NULL) {
    6903           0 :                 goto fail;
    6904             :         }
    6905           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6906           4 :         if (!NT_STATUS_IS_OK(status)) {
    6907           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6908             :                         fname, nt_errstr(status));
    6909           0 :                 goto fail;
    6910             :         }
    6911           4 :         status = cli_close(cli, fnum);
    6912           4 :         if (!NT_STATUS_IS_OK(status)) {
    6913           0 :                 printf("close failed for %s (%s)\n",
    6914             :                         fname, nt_errstr(status));
    6915           0 :                 goto fail;
    6916             :         }
    6917           4 :         fnum = (uint16_t)-1;
    6918             : 
    6919             :         /* Try and open for FILE_WRITE_DATA */
    6920           4 :         status = cli_ntcreate(cli,
    6921             :                                 fname,
    6922             :                                 0,
    6923             :                                 FILE_WRITE_DATA,
    6924             :                                 FILE_ATTRIBUTE_NORMAL,
    6925             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6926             :                                         FILE_SHARE_DELETE,
    6927             :                                 FILE_OPEN,
    6928             :                                 0,
    6929             :                                 0,
    6930             :                                 &fnum,
    6931             :                                 NULL);
    6932           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6933           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6934           0 :                 goto fail;
    6935             :         }
    6936             : 
    6937             :         /* Now try and open for FILE_READ_DATA */
    6938           4 :         status = cli_ntcreate(cli,
    6939             :                                 fname,
    6940             :                                 0,
    6941             :                                 FILE_READ_DATA,
    6942             :                                 FILE_ATTRIBUTE_NORMAL,
    6943             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6944             :                                         FILE_SHARE_DELETE,
    6945             :                                 FILE_OPEN,
    6946             :                                 0,
    6947             :                                 0,
    6948             :                                 &fnum,
    6949             :                                 NULL);
    6950           4 :         if (!NT_STATUS_IS_OK(status)) {
    6951           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6952           0 :                 goto fail;
    6953             :         }
    6954             : 
    6955           4 :         status = cli_close(cli, fnum);
    6956           4 :         if (!NT_STATUS_IS_OK(status)) {
    6957           0 :                 printf("close failed for %s (%s)\n",
    6958             :                         fname, nt_errstr(status));
    6959           0 :                 goto fail;
    6960             :         }
    6961             : 
    6962             :         /* Restore clean slate. */
    6963           4 :         TALLOC_FREE(sd);
    6964           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6965             : 
    6966             :         /* Create the test file. */
    6967           4 :         status = cli_ntcreate(cli,
    6968             :                                 fname,
    6969             :                                 0,
    6970             :                                 GENERIC_ALL_ACCESS,
    6971             :                                 FILE_ATTRIBUTE_NORMAL,
    6972             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6973             :                                         FILE_SHARE_DELETE,
    6974             :                                 FILE_CREATE,
    6975             :                                 0,
    6976             :                                 0,
    6977             :                                 &fnum,
    6978             :                                 NULL);
    6979           4 :         if (!NT_STATUS_IS_OK(status)) {
    6980           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6981           0 :                 goto fail;
    6982             :         }
    6983             : 
    6984             :         /* Get the original SD. */
    6985           4 :         status = cli_query_secdesc(cli,
    6986             :                                 fnum,
    6987             :                                 frame,
    6988             :                                 &sd);
    6989           4 :         if (!NT_STATUS_IS_OK(status)) {
    6990           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6991             :                         fname, nt_errstr(status));
    6992           0 :                 goto fail;
    6993             :         }
    6994             : 
    6995             :         /*
    6996             :          * Add an "owner-rights ACE denying WRITE_DATA,
    6997             :          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
    6998             :          */
    6999             : 
    7000           4 :         newsd = security_descriptor_dacl_create(frame,
    7001             :                                         0,
    7002             :                                         NULL,
    7003             :                                         NULL,
    7004             :                                         SID_OWNER_RIGHTS,
    7005             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7006             :                                         FILE_WRITE_DATA,
    7007             :                                         0,
    7008             :                                         SID_OWNER_RIGHTS,
    7009             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7010             :                                         FILE_READ_DATA|FILE_WRITE_DATA,
    7011             :                                         0,
    7012             :                                         NULL);
    7013           4 :         if (newsd == NULL) {
    7014           0 :                 goto fail;
    7015             :         }
    7016           8 :         sd->dacl = security_acl_concatenate(frame,
    7017           4 :                                         newsd->dacl,
    7018           4 :                                         sd->dacl);
    7019           4 :         if (sd->dacl == NULL) {
    7020           0 :                 goto fail;
    7021             :         }
    7022           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7023           4 :         if (!NT_STATUS_IS_OK(status)) {
    7024           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7025             :                         fname, nt_errstr(status));
    7026           0 :                 goto fail;
    7027             :         }
    7028           4 :         status = cli_close(cli, fnum);
    7029           4 :         if (!NT_STATUS_IS_OK(status)) {
    7030           0 :                 printf("close failed for %s (%s)\n",
    7031             :                         fname, nt_errstr(status));
    7032           0 :                 goto fail;
    7033             :         }
    7034           4 :         fnum = (uint16_t)-1;
    7035             : 
    7036             :         /* Try and open for FILE_WRITE_DATA */
    7037           4 :         status = cli_ntcreate(cli,
    7038             :                                 fname,
    7039             :                                 0,
    7040             :                                 FILE_WRITE_DATA,
    7041             :                                 FILE_ATTRIBUTE_NORMAL,
    7042             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7043             :                                         FILE_SHARE_DELETE,
    7044             :                                 FILE_OPEN,
    7045             :                                 0,
    7046             :                                 0,
    7047             :                                 &fnum,
    7048             :                                 NULL);
    7049           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    7050           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7051           0 :                 goto fail;
    7052             :         }
    7053             : 
    7054             :         /* Now try and open for FILE_READ_DATA */
    7055           4 :         status = cli_ntcreate(cli,
    7056             :                                 fname,
    7057             :                                 0,
    7058             :                                 FILE_READ_DATA,
    7059             :                                 FILE_ATTRIBUTE_NORMAL,
    7060             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7061             :                                         FILE_SHARE_DELETE,
    7062             :                                 FILE_OPEN,
    7063             :                                 0,
    7064             :                                 0,
    7065             :                                 &fnum,
    7066             :                                 NULL);
    7067           4 :         if (!NT_STATUS_IS_OK(status)) {
    7068           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7069           0 :                 goto fail;
    7070             :         }
    7071             : 
    7072           4 :         status = cli_close(cli, fnum);
    7073           4 :         if (!NT_STATUS_IS_OK(status)) {
    7074           0 :                 printf("close failed for %s (%s)\n",
    7075             :                         fname, nt_errstr(status));
    7076           0 :                 goto fail;
    7077             :         }
    7078             : 
    7079             :         /* Restore clean slate. */
    7080           4 :         TALLOC_FREE(sd);
    7081           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7082             : 
    7083             : 
    7084             :         /* Create the test file. */
    7085           4 :         status = cli_ntcreate(cli,
    7086             :                                 fname,
    7087             :                                 0,
    7088             :                                 GENERIC_ALL_ACCESS,
    7089             :                                 FILE_ATTRIBUTE_NORMAL,
    7090             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7091             :                                         FILE_SHARE_DELETE,
    7092             :                                 FILE_CREATE,
    7093             :                                 0,
    7094             :                                 0,
    7095             :                                 &fnum,
    7096             :                                 NULL);
    7097           4 :         if (!NT_STATUS_IS_OK(status)) {
    7098           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7099           0 :                 goto fail;
    7100             :         }
    7101             : 
    7102             :         /* Get the original SD. */
    7103           4 :         status = cli_query_secdesc(cli,
    7104             :                                 fnum,
    7105             :                                 frame,
    7106             :                                 &sd);
    7107           4 :         if (!NT_STATUS_IS_OK(status)) {
    7108           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    7109             :                         fname, nt_errstr(status));
    7110           0 :                 goto fail;
    7111             :         }
    7112             : 
    7113             :         /*
    7114             :          * Add an "authenticated users" ACE allowing READ_DATA,
    7115             :          * add an "owner-rights" denying READ_DATA,
    7116             :          * and an "authenticated users" ACE allowing WRITE_DATA.
    7117             :          */
    7118             : 
    7119           4 :         newsd = security_descriptor_dacl_create(frame,
    7120             :                                         0,
    7121             :                                         NULL,
    7122             :                                         NULL,
    7123             :                                         SID_NT_AUTHENTICATED_USERS,
    7124             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7125             :                                         FILE_READ_DATA,
    7126             :                                         0,
    7127             :                                         SID_OWNER_RIGHTS,
    7128             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7129             :                                         FILE_READ_DATA,
    7130             :                                         0,
    7131             :                                         SID_NT_AUTHENTICATED_USERS,
    7132             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7133             :                                         FILE_WRITE_DATA,
    7134             :                                         0,
    7135             :                                         NULL);
    7136           4 :         if (newsd == NULL) {
    7137           0 :                 printf("newsd == NULL\n");
    7138           0 :                 goto fail;
    7139             :         }
    7140           8 :         sd->dacl = security_acl_concatenate(frame,
    7141           4 :                                         newsd->dacl,
    7142           4 :                                         sd->dacl);
    7143           4 :         if (sd->dacl == NULL) {
    7144           0 :                 printf("sd->dacl == NULL\n");
    7145           0 :                 goto fail;
    7146             :         }
    7147           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7148           4 :         if (!NT_STATUS_IS_OK(status)) {
    7149           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7150             :                         fname, nt_errstr(status));
    7151           0 :                 goto fail;
    7152             :         }
    7153           4 :         status = cli_close(cli, fnum);
    7154           4 :         if (!NT_STATUS_IS_OK(status)) {
    7155           0 :                 printf("close failed for %s (%s)\n",
    7156             :                         fname, nt_errstr(status));
    7157           0 :                 goto fail;
    7158             :         }
    7159           4 :         fnum = (uint16_t)-1;
    7160             : 
    7161             :         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
    7162           4 :         status = cli_ntcreate(cli,
    7163             :                                 fname,
    7164             :                                 0,
    7165             :                                 FILE_READ_DATA|FILE_WRITE_DATA,
    7166             :                                 FILE_ATTRIBUTE_NORMAL,
    7167             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7168             :                                         FILE_SHARE_DELETE,
    7169             :                                 FILE_OPEN,
    7170             :                                 0,
    7171             :                                 0,
    7172             :                                 &fnum,
    7173             :                                 NULL);
    7174           4 :         if (!NT_STATUS_IS_OK(status)) {
    7175           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7176           0 :                 goto fail;
    7177             :         }
    7178             : 
    7179           4 :         status = cli_close(cli, fnum);
    7180           4 :         if (!NT_STATUS_IS_OK(status)) {
    7181           0 :                 printf("close failed for %s (%s)\n",
    7182             :                         fname, nt_errstr(status));
    7183           0 :                 goto fail;
    7184             :         }
    7185             : 
    7186           4 :         cli_unlink(cli, fname,
    7187             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7188             : 
    7189           4 :         TALLOC_FREE(frame);
    7190           4 :         return true;
    7191             : 
    7192           0 :   fail:
    7193             : 
    7194           0 :         if (cli) {
    7195           0 :                 if (fnum != (uint16_t)-1) {
    7196           0 :                         cli_close(cli, fnum);
    7197             :                 }
    7198           0 :                 cli_unlink(cli, fname,
    7199             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7200           0 :                 torture_close_connection(cli);
    7201             :         }
    7202             : 
    7203           0 :         TALLOC_FREE(frame);
    7204           0 :         return false;
    7205             : }
    7206             : 
    7207             : /*
    7208             :  * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
    7209             :  * Note this test only works with a user with SeSecurityPrivilege set.
    7210             :  *
    7211             :  * NB. This is also tested in samba3.base.createx_access
    7212             :  * but this makes it very explicit what we're looking for.
    7213             :  */
    7214           2 : static bool run_smb1_system_security(int dummy)
    7215             : {
    7216           0 :         static struct cli_state *cli = NULL;
    7217           2 :         const char *fname = "system_security.txt";
    7218           2 :         uint16_t fnum = (uint16_t)-1;
    7219           0 :         NTSTATUS status;
    7220           2 :         TALLOC_CTX *frame = NULL;
    7221             : 
    7222           2 :         frame = talloc_stackframe();
    7223           2 :         printf("starting smb1 system security test\n");
    7224             : 
    7225             :         /* SMB1 connection - torture_open_connection() forces this. */
    7226           2 :         if (!torture_open_connection(&cli, 0)) {
    7227           0 :                 goto fail;
    7228             :         }
    7229             : 
    7230           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    7231             : 
    7232             :         /* Start with a clean slate. */
    7233           2 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7234             : 
    7235             :         /* Create the test file. */
    7236           2 :         status = cli_ntcreate(cli,
    7237             :                                 fname,
    7238             :                                 0,
    7239             :                                 GENERIC_ALL_ACCESS,
    7240             :                                 FILE_ATTRIBUTE_NORMAL,
    7241             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7242             :                                         FILE_SHARE_DELETE,
    7243             :                                 FILE_CREATE,
    7244             :                                 0,
    7245             :                                 0,
    7246             :                                 &fnum,
    7247             :                                 NULL);
    7248           2 :         if (!NT_STATUS_IS_OK(status)) {
    7249           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7250           0 :                 goto fail;
    7251             :         }
    7252             : 
    7253           2 :         status = cli_close(cli, fnum);
    7254             : 
    7255             :         /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
    7256             :         /*
    7257             :          * On SMB1 this succeeds - SMB2 it fails,
    7258             :          * see the SMB2-SACL test.
    7259             :          */
    7260           2 :         status = cli_ntcreate(cli,
    7261             :                                 fname,
    7262             :                                 0,
    7263             :                                 SEC_FLAG_SYSTEM_SECURITY,
    7264             :                                 FILE_ATTRIBUTE_NORMAL,
    7265             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7266             :                                         FILE_SHARE_DELETE,
    7267             :                                 FILE_OPEN,
    7268             :                                 0,
    7269             :                                 0,
    7270             :                                 &fnum,
    7271             :                                 NULL);
    7272           2 :         if (!NT_STATUS_IS_OK(status)) {
    7273           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7274           0 :                 goto fail;
    7275             :         }
    7276             : 
    7277           2 :         status = cli_close(cli, fnum);
    7278             : 
    7279           2 :         cli_unlink(cli, fname,
    7280             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7281             : 
    7282           2 :         torture_close_connection(cli);
    7283           2 :         TALLOC_FREE(frame);
    7284           2 :         return true;
    7285             : 
    7286           0 :   fail:
    7287             : 
    7288           0 :         if (cli) {
    7289           0 :                 if (fnum != (uint16_t)-1) {
    7290           0 :                         cli_close(cli, fnum);
    7291             :                 }
    7292           0 :                 cli_unlink(cli, fname,
    7293             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7294           0 :                 torture_close_connection(cli);
    7295             :         }
    7296             : 
    7297           0 :         TALLOC_FREE(frame);
    7298           0 :         return false;
    7299             : }
    7300             : 
    7301           0 : static bool run_pipe_number(int dummy)
    7302             : {
    7303           0 :         struct cli_state *cli1;
    7304           0 :         const char *pipe_name = "\\SPOOLSS";
    7305           0 :         uint16_t fnum;
    7306           0 :         int num_pipes = 0;
    7307           0 :         NTSTATUS status;
    7308             : 
    7309           0 :         printf("starting pipenumber test\n");
    7310           0 :         if (!torture_open_connection(&cli1, 0)) {
    7311           0 :                 return False;
    7312             :         }
    7313             : 
    7314           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7315           0 :         while(1) {
    7316           0 :                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
    7317             :                                       FILE_ATTRIBUTE_NORMAL,
    7318             :                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
    7319             :                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
    7320           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7321           0 :                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
    7322           0 :                         break;
    7323             :                 }
    7324           0 :                 num_pipes++;
    7325           0 :                 printf("\r%6d", num_pipes);
    7326             :         }
    7327             : 
    7328           0 :         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
    7329           0 :         torture_close_connection(cli1);
    7330           0 :         return True;
    7331             : }
    7332             : 
    7333             : /*
    7334             :   Test open mode returns on read-only files.
    7335             :  */
    7336           5 : static bool run_opentest(int dummy)
    7337             : {
    7338           0 :         static struct cli_state *cli1;
    7339           0 :         static struct cli_state *cli2;
    7340           5 :         const char *fname = "\\readonly.file";
    7341           0 :         uint16_t fnum1, fnum2;
    7342           0 :         char buf[20];
    7343           0 :         off_t fsize;
    7344           5 :         bool correct = True;
    7345           0 :         char *tmp_path;
    7346           0 :         NTSTATUS status;
    7347             : 
    7348           5 :         printf("starting open test\n");
    7349             : 
    7350           5 :         if (!torture_open_connection(&cli1, 0)) {
    7351           0 :                 return False;
    7352             :         }
    7353             : 
    7354           5 :         cli_setatr(cli1, fname, 0, 0);
    7355           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7356             : 
    7357           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7358             : 
    7359           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7360           5 :         if (!NT_STATUS_IS_OK(status)) {
    7361           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7362           0 :                 return False;
    7363             :         }
    7364             : 
    7365           5 :         status = cli_close(cli1, fnum1);
    7366           5 :         if (!NT_STATUS_IS_OK(status)) {
    7367           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7368           0 :                 return False;
    7369             :         }
    7370             : 
    7371           5 :         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
    7372           5 :         if (!NT_STATUS_IS_OK(status)) {
    7373           0 :                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
    7374           0 :                 return False;
    7375             :         }
    7376             : 
    7377           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7378           5 :         if (!NT_STATUS_IS_OK(status)) {
    7379           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7380           0 :                 return False;
    7381             :         }
    7382             : 
    7383             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
    7384           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7385             : 
    7386           5 :         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
    7387           5 :                         NT_STATUS_ACCESS_DENIED)) {
    7388           4 :                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
    7389             :         }
    7390             : 
    7391           5 :         printf("finished open test 1\n");
    7392             : 
    7393           5 :         cli_close(cli1, fnum1);
    7394             : 
    7395             :         /* Now try not readonly and ensure ERRbadshare is returned. */
    7396             : 
    7397           5 :         cli_setatr(cli1, fname, 0, 0);
    7398             : 
    7399           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7400           5 :         if (!NT_STATUS_IS_OK(status)) {
    7401           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7402           0 :                 return False;
    7403             :         }
    7404             : 
    7405             :         /* This will fail - but the error should be ERRshare. */
    7406           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7407             : 
    7408           5 :         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
    7409           5 :                         NT_STATUS_SHARING_VIOLATION)) {
    7410           5 :                 printf("correct error code ERRDOS/ERRbadshare returned\n");
    7411             :         }
    7412             : 
    7413           5 :         status = cli_close(cli1, fnum1);
    7414           5 :         if (!NT_STATUS_IS_OK(status)) {
    7415           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7416           0 :                 return False;
    7417             :         }
    7418             : 
    7419           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7420             : 
    7421           5 :         printf("finished open test 2\n");
    7422             : 
    7423             :         /* Test truncate open disposition on file opened for read. */
    7424           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7425           5 :         if (!NT_STATUS_IS_OK(status)) {
    7426           0 :                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
    7427           0 :                 return False;
    7428             :         }
    7429             : 
    7430             :         /* write 20 bytes. */
    7431             : 
    7432           5 :         memset(buf, '\0', 20);
    7433             : 
    7434           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
    7435           5 :         if (!NT_STATUS_IS_OK(status)) {
    7436           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    7437           0 :                 correct = False;
    7438             :         }
    7439             : 
    7440           5 :         status = cli_close(cli1, fnum1);
    7441           5 :         if (!NT_STATUS_IS_OK(status)) {
    7442           0 :                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
    7443           0 :                 return False;
    7444             :         }
    7445             : 
    7446             :         /* Ensure size == 20. */
    7447           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7448           5 :         if (!NT_STATUS_IS_OK(status)) {
    7449           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7450           0 :                 return False;
    7451             :         }
    7452             : 
    7453           5 :         if (fsize != 20) {
    7454           0 :                 printf("(3) file size != 20\n");
    7455           0 :                 return False;
    7456             :         }
    7457             : 
    7458             :         /* Now test if we can truncate a file opened for readonly. */
    7459           5 :         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
    7460           5 :         if (!NT_STATUS_IS_OK(status)) {
    7461           0 :                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
    7462           0 :                 return False;
    7463             :         }
    7464             : 
    7465           5 :         status = cli_close(cli1, fnum1);
    7466           5 :         if (!NT_STATUS_IS_OK(status)) {
    7467           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7468           0 :                 return False;
    7469             :         }
    7470             : 
    7471             :         /* Ensure size == 0. */
    7472           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7473           5 :         if (!NT_STATUS_IS_OK(status)) {
    7474           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7475           0 :                 return False;
    7476             :         }
    7477             : 
    7478           5 :         if (fsize != 0) {
    7479           0 :                 printf("(3) file size != 0\n");
    7480           0 :                 return False;
    7481             :         }
    7482           5 :         printf("finished open test 3\n");
    7483             : 
    7484           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7485             : 
    7486           5 :         printf("Do ctemp tests\n");
    7487           5 :         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
    7488           5 :         if (!NT_STATUS_IS_OK(status)) {
    7489           0 :                 printf("ctemp failed (%s)\n", nt_errstr(status));
    7490           0 :                 return False;
    7491             :         }
    7492             : 
    7493           5 :         printf("ctemp gave path %s\n", tmp_path);
    7494           5 :         status = cli_close(cli1, fnum1);
    7495           5 :         if (!NT_STATUS_IS_OK(status)) {
    7496           0 :                 printf("close of temp failed (%s)\n", nt_errstr(status));
    7497             :         }
    7498             : 
    7499           5 :         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7500           5 :         if (!NT_STATUS_IS_OK(status)) {
    7501           0 :                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
    7502             :         }
    7503             : 
    7504             :         /* Test the non-io opens... */
    7505             : 
    7506           5 :         if (!torture_open_connection(&cli2, 1)) {
    7507           0 :                 return False;
    7508             :         }
    7509             : 
    7510           5 :         cli_setatr(cli2, fname, 0, 0);
    7511           5 :         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7512             : 
    7513           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    7514             : 
    7515           5 :         printf("TEST #1 testing 2 non-io opens (no delete)\n");
    7516           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7517             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7518             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7519           5 :         if (!NT_STATUS_IS_OK(status)) {
    7520           0 :                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7521           0 :                 return False;
    7522             :         }
    7523             : 
    7524           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7525             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7526             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7527           5 :         if (!NT_STATUS_IS_OK(status)) {
    7528           0 :                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7529           0 :                 return False;
    7530             :         }
    7531             : 
    7532           5 :         status = cli_close(cli1, fnum1);
    7533           5 :         if (!NT_STATUS_IS_OK(status)) {
    7534           0 :                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7535           0 :                 return False;
    7536             :         }
    7537             : 
    7538           5 :         status = cli_close(cli2, fnum2);
    7539           5 :         if (!NT_STATUS_IS_OK(status)) {
    7540           0 :                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7541           0 :                 return False;
    7542             :         }
    7543             : 
    7544           5 :         printf("non-io open test #1 passed.\n");
    7545             : 
    7546           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7547             : 
    7548           5 :         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
    7549             : 
    7550           5 :         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           5 :         if (!NT_STATUS_IS_OK(status)) {
    7555           0 :                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7556           0 :                 return False;
    7557             :         }
    7558             : 
    7559           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7560             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7561             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7562           5 :         if (!NT_STATUS_IS_OK(status)) {
    7563           0 :                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7564           0 :                 return False;
    7565             :         }
    7566             : 
    7567           5 :         status = cli_close(cli1, fnum1);
    7568           5 :         if (!NT_STATUS_IS_OK(status)) {
    7569           0 :                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7570           0 :                 return False;
    7571             :         }
    7572             : 
    7573           5 :         status = cli_close(cli2, fnum2);
    7574           5 :         if (!NT_STATUS_IS_OK(status)) {
    7575           0 :                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7576           0 :                 return False;
    7577             :         }
    7578             : 
    7579           5 :         printf("non-io open test #2 passed.\n");
    7580             : 
    7581           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7582             : 
    7583           5 :         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
    7584             : 
    7585           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7586             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7587             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7588           5 :         if (!NT_STATUS_IS_OK(status)) {
    7589           0 :                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7590           0 :                 return False;
    7591             :         }
    7592             : 
    7593           5 :         status = cli_ntcreate(cli2, fname, 0,
    7594             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7595             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7596             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7597           5 :         if (!NT_STATUS_IS_OK(status)) {
    7598           0 :                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7599           0 :                 return False;
    7600             :         }
    7601             : 
    7602           5 :         status = cli_close(cli1, fnum1);
    7603           5 :         if (!NT_STATUS_IS_OK(status)) {
    7604           0 :                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7605           0 :                 return False;
    7606             :         }
    7607             : 
    7608           5 :         status = cli_close(cli2, fnum2);
    7609           5 :         if (!NT_STATUS_IS_OK(status)) {
    7610           0 :                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7611           0 :                 return False;
    7612             :         }
    7613             : 
    7614           5 :         printf("non-io open test #3 passed.\n");
    7615             : 
    7616           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7617             : 
    7618           5 :         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
    7619             : 
    7620           5 :         status = cli_ntcreate(cli1, fname, 0,
    7621             :                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7622             :                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7623             :                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7624           5 :         if (!NT_STATUS_IS_OK(status)) {
    7625           0 :                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7626           0 :                 return False;
    7627             :         }
    7628             : 
    7629           5 :         status = cli_ntcreate(cli2, fname, 0,
    7630             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7631             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7632             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7633           5 :         if (NT_STATUS_IS_OK(status)) {
    7634           0 :                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7635           0 :                 return False;
    7636             :         }
    7637             : 
    7638           5 :         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7639             : 
    7640           5 :         status = cli_close(cli1, fnum1);
    7641           5 :         if (!NT_STATUS_IS_OK(status)) {
    7642           0 :                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7643           0 :                 return False;
    7644             :         }
    7645             : 
    7646           5 :         printf("non-io open test #4 passed.\n");
    7647             : 
    7648           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7649             : 
    7650           5 :         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    7651             : 
    7652           5 :         status = cli_ntcreate(cli1, fname, 0,
    7653             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7654             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7655             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7656           5 :         if (!NT_STATUS_IS_OK(status)) {
    7657           0 :                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7658           0 :                 return False;
    7659             :         }
    7660             : 
    7661           5 :         status = cli_ntcreate(cli2, fname, 0,
    7662             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7663             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7664             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7665           5 :         if (!NT_STATUS_IS_OK(status)) {
    7666           0 :                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7667           0 :                 return False;
    7668             :         }
    7669             : 
    7670           5 :         status = cli_close(cli1, fnum1);
    7671           5 :         if (!NT_STATUS_IS_OK(status)) {
    7672           0 :                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7673           0 :                 return False;
    7674             :         }
    7675             : 
    7676           5 :         status = cli_close(cli2, fnum2);
    7677           5 :         if (!NT_STATUS_IS_OK(status)) {
    7678           0 :                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7679           0 :                 return False;
    7680             :         }
    7681             : 
    7682           5 :         printf("non-io open test #5 passed.\n");
    7683             : 
    7684           5 :         printf("TEST #6 testing 1 non-io open, one io open\n");
    7685             : 
    7686           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7687             : 
    7688           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7689             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7690             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7691           5 :         if (!NT_STATUS_IS_OK(status)) {
    7692           0 :                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7693           0 :                 return False;
    7694             :         }
    7695             : 
    7696           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7697             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    7698             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7699           5 :         if (!NT_STATUS_IS_OK(status)) {
    7700           0 :                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7701           0 :                 return False;
    7702             :         }
    7703             : 
    7704           5 :         status = cli_close(cli1, fnum1);
    7705           5 :         if (!NT_STATUS_IS_OK(status)) {
    7706           0 :                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7707           0 :                 return False;
    7708             :         }
    7709             : 
    7710           5 :         status = cli_close(cli2, fnum2);
    7711           5 :         if (!NT_STATUS_IS_OK(status)) {
    7712           0 :                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7713           0 :                 return False;
    7714             :         }
    7715             : 
    7716           5 :         printf("non-io open test #6 passed.\n");
    7717             : 
    7718           5 :         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
    7719             : 
    7720           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7721             : 
    7722           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7723             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7724             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7725           5 :         if (!NT_STATUS_IS_OK(status)) {
    7726           0 :                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7727           0 :                 return False;
    7728             :         }
    7729             : 
    7730           5 :         status = cli_ntcreate(cli2, fname, 0,
    7731             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7732             :                               FILE_ATTRIBUTE_NORMAL,
    7733             :                               FILE_SHARE_READ|FILE_SHARE_DELETE,
    7734             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7735           5 :         if (NT_STATUS_IS_OK(status)) {
    7736           0 :                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7737           0 :                 return False;
    7738             :         }
    7739             : 
    7740           5 :         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7741             : 
    7742           5 :         status = cli_close(cli1, fnum1);
    7743           5 :         if (!NT_STATUS_IS_OK(status)) {
    7744           0 :                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7745           0 :                 return False;
    7746             :         }
    7747             : 
    7748           5 :         printf("non-io open test #7 passed.\n");
    7749             : 
    7750           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7751             : 
    7752           5 :         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
    7753           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
    7754             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7755             :                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7756           5 :         if (!NT_STATUS_IS_OK(status)) {
    7757           0 :                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
    7758           0 :                 correct = false;
    7759           0 :                 goto out;
    7760             :         }
    7761             : 
    7762             :         /* Write to ensure we have to update the file time. */
    7763           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7764             :                               NULL);
    7765           5 :         if (!NT_STATUS_IS_OK(status)) {
    7766           0 :                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
    7767           0 :                 correct = false;
    7768           0 :                 goto out;
    7769             :         }
    7770             : 
    7771           5 :         status = cli_close(cli1, fnum1);
    7772           5 :         if (!NT_STATUS_IS_OK(status)) {
    7773           0 :                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
    7774           0 :                 correct = false;
    7775             :         }
    7776             : 
    7777           5 :   out:
    7778             : 
    7779           5 :         if (!torture_close_connection(cli1)) {
    7780           0 :                 correct = False;
    7781             :         }
    7782           5 :         if (!torture_close_connection(cli2)) {
    7783           0 :                 correct = False;
    7784             :         }
    7785             : 
    7786           5 :         return correct;
    7787             : }
    7788             : 
    7789         102 : NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
    7790             : {
    7791           0 :         uint16_t major, minor;
    7792           0 :         uint32_t caplow, caphigh;
    7793           0 :         NTSTATUS status;
    7794             : 
    7795         102 :         if (!SERVER_HAS_UNIX_CIFS(cli)) {
    7796           0 :                 printf("Server doesn't support UNIX CIFS extensions.\n");
    7797           0 :                 return NT_STATUS_NOT_SUPPORTED;
    7798             :         }
    7799             : 
    7800         102 :         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
    7801             :                                              &caphigh);
    7802         102 :         if (!NT_STATUS_IS_OK(status)) {
    7803           0 :                 printf("Server didn't return UNIX CIFS extensions: %s\n",
    7804             :                        nt_errstr(status));
    7805           0 :                 return status;
    7806             :         }
    7807             : 
    7808         102 :         status = cli_set_unix_extensions_capabilities(cli, major, minor,
    7809             :                                                       caplow, caphigh);
    7810         102 :         if (!NT_STATUS_IS_OK(status)) {
    7811           0 :                 printf("Server doesn't support setting UNIX CIFS extensions: "
    7812             :                        "%s.\n", nt_errstr(status));
    7813           0 :                 return status;
    7814             :         }
    7815             : 
    7816         102 :         return NT_STATUS_OK;
    7817             : }
    7818             : 
    7819             : /*
    7820             :   Test POSIX open /mkdir calls.
    7821             :  */
    7822           4 : static bool run_simple_posix_open_test(int dummy)
    7823             : {
    7824           0 :         static struct cli_state *cli1;
    7825           4 :         const char *fname = "posix:file";
    7826           4 :         const char *hname = "posix:hlink";
    7827           4 :         const char *sname = "posix:symlink";
    7828           4 :         const char *dname = "posix:dir";
    7829           0 :         char buf[10];
    7830           4 :         char *target = NULL;
    7831           4 :         uint16_t fnum1 = (uint16_t)-1;
    7832           0 :         SMB_STRUCT_STAT sbuf;
    7833           4 :         bool correct = false;
    7834           0 :         NTSTATUS status;
    7835           0 :         size_t nread;
    7836           4 :         const char *fname_windows = "windows_file";
    7837           4 :         uint16_t fnum2 = (uint16_t)-1;
    7838           0 :         bool ok;
    7839             : 
    7840           4 :         printf("Starting simple POSIX open test\n");
    7841             : 
    7842           4 :         if (!torture_open_connection(&cli1, 0)) {
    7843           0 :                 return false;
    7844             :         }
    7845             : 
    7846           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7847             : 
    7848           4 :         status = torture_setup_unix_extensions(cli1);
    7849           4 :         if (!NT_STATUS_IS_OK(status)) {
    7850           0 :                 return false;
    7851             :         }
    7852             : 
    7853           4 :         cli_setatr(cli1, fname, 0, 0);
    7854           4 :         cli_posix_unlink(cli1, fname);
    7855           4 :         cli_setatr(cli1, dname, 0, 0);
    7856           4 :         cli_posix_rmdir(cli1, dname);
    7857           4 :         cli_setatr(cli1, hname, 0, 0);
    7858           4 :         cli_posix_unlink(cli1, hname);
    7859           4 :         cli_setatr(cli1, sname, 0, 0);
    7860           4 :         cli_posix_unlink(cli1, sname);
    7861           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    7862           4 :         cli_posix_unlink(cli1, fname_windows);
    7863             : 
    7864             :         /* Create a directory. */
    7865           4 :         status = cli_posix_mkdir(cli1, dname, 0777);
    7866           4 :         if (!NT_STATUS_IS_OK(status)) {
    7867           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7868           0 :                 goto out;
    7869             :         }
    7870             : 
    7871           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7872             :                                 0600, &fnum1);
    7873           4 :         if (!NT_STATUS_IS_OK(status)) {
    7874           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7875           0 :                 goto out;
    7876             :         }
    7877             : 
    7878             :         /* Test ftruncate - set file size. */
    7879           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7880           4 :         if (!NT_STATUS_IS_OK(status)) {
    7881           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7882           0 :                 goto out;
    7883             :         }
    7884             : 
    7885             :         /* Ensure st_size == 1000 */
    7886           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7887           4 :         if (!NT_STATUS_IS_OK(status)) {
    7888           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7889           0 :                 goto out;
    7890             :         }
    7891             : 
    7892           4 :         if (sbuf.st_ex_size != 1000) {
    7893           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7894           0 :                 goto out;
    7895             :         }
    7896             : 
    7897             :         /* Ensure st_mode == 0600 */
    7898           4 :         if ((sbuf.st_ex_mode & 07777) != 0600) {
    7899           0 :                 printf("posix_open - bad permissions 0%o != 0600\n",
    7900           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7901           0 :                 goto out;
    7902             :         }
    7903             : 
    7904             :         /* Test ftruncate - set file size back to zero. */
    7905           4 :         status = cli_ftruncate(cli1, fnum1, 0);
    7906           4 :         if (!NT_STATUS_IS_OK(status)) {
    7907           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7908           0 :                 goto out;
    7909             :         }
    7910             : 
    7911           4 :         status = cli_close(cli1, fnum1);
    7912           4 :         if (!NT_STATUS_IS_OK(status)) {
    7913           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7914           0 :                 goto out;
    7915             :         }
    7916             : 
    7917             :         /* Now open the file again for read only. */
    7918           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7919           4 :         if (!NT_STATUS_IS_OK(status)) {
    7920           0 :                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
    7921           0 :                 goto out;
    7922             :         }
    7923             : 
    7924             :         /* Now unlink while open. */
    7925           4 :         status = cli_posix_unlink(cli1, fname);
    7926           4 :         if (!NT_STATUS_IS_OK(status)) {
    7927           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7928           0 :                 goto out;
    7929             :         }
    7930             : 
    7931           4 :         status = cli_close(cli1, fnum1);
    7932           4 :         if (!NT_STATUS_IS_OK(status)) {
    7933           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7934           0 :                 goto out;
    7935             :         }
    7936             : 
    7937             :         /* Ensure the file has gone. */
    7938           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7939           4 :         if (NT_STATUS_IS_OK(status)) {
    7940           0 :                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
    7941           0 :                 goto out;
    7942             :         }
    7943             : 
    7944             :         /* Create again to test open with O_TRUNC. */
    7945           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
    7946           4 :         if (!NT_STATUS_IS_OK(status)) {
    7947           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7948           0 :                 goto out;
    7949             :         }
    7950             : 
    7951             :         /* Test ftruncate - set file size. */
    7952           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7953           4 :         if (!NT_STATUS_IS_OK(status)) {
    7954           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7955           0 :                 goto out;
    7956             :         }
    7957             : 
    7958             :         /* Ensure st_size == 1000 */
    7959           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7960           4 :         if (!NT_STATUS_IS_OK(status)) {
    7961           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7962           0 :                 goto out;
    7963             :         }
    7964             : 
    7965           4 :         if (sbuf.st_ex_size != 1000) {
    7966           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7967           0 :                 goto out;
    7968             :         }
    7969             : 
    7970           4 :         status = cli_close(cli1, fnum1);
    7971           4 :         if (!NT_STATUS_IS_OK(status)) {
    7972           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7973           0 :                 goto out;
    7974             :         }
    7975             : 
    7976             :         /* Re-open with O_TRUNC. */
    7977           4 :         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
    7978           4 :         if (!NT_STATUS_IS_OK(status)) {
    7979           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7980           0 :                 goto out;
    7981             :         }
    7982             : 
    7983             :         /* Ensure st_size == 0 */
    7984           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7985           4 :         if (!NT_STATUS_IS_OK(status)) {
    7986           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7987           0 :                 goto out;
    7988             :         }
    7989             : 
    7990           4 :         if (sbuf.st_ex_size != 0) {
    7991           0 :                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
    7992           0 :                 goto out;
    7993             :         }
    7994             : 
    7995           4 :         status = cli_close(cli1, fnum1);
    7996           4 :         if (!NT_STATUS_IS_OK(status)) {
    7997           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7998           0 :                 goto out;
    7999             :         }
    8000             : 
    8001           4 :         status = cli_posix_unlink(cli1, fname);
    8002           4 :         if (!NT_STATUS_IS_OK(status)) {
    8003           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    8004           0 :                 goto out;
    8005             :         }
    8006             : 
    8007           4 :         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
    8008           4 :         if (!NT_STATUS_IS_OK(status)) {
    8009           0 :                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
    8010             :                         dname, nt_errstr(status));
    8011           0 :                 goto out;
    8012             :         }
    8013             : 
    8014           4 :         cli_close(cli1, fnum1);
    8015             : 
    8016             :         /* What happens when we try and POSIX open a directory for write ? */
    8017           4 :         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
    8018           4 :         if (NT_STATUS_IS_OK(status)) {
    8019           0 :                 printf("POSIX open of directory %s succeeded, "
    8020             :                        "should have failed.\n",
    8021             :                        dname);
    8022           0 :                 goto out;
    8023             :         } else {
    8024           4 :                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
    8025           4 :                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
    8026           0 :                         goto out;
    8027             :                 }
    8028             :         }
    8029             : 
    8030             :         /* Create the file. */
    8031           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    8032             :                                 0600, &fnum1);
    8033           4 :         if (!NT_STATUS_IS_OK(status)) {
    8034           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    8035           0 :                 goto out;
    8036             :         }
    8037             : 
    8038             :         /* Write some data into it. */
    8039           4 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    8040             :                               NULL);
    8041           4 :         if (!NT_STATUS_IS_OK(status)) {
    8042           0 :                 printf("cli_write failed: %s\n", nt_errstr(status));
    8043           0 :                 goto out;
    8044             :         }
    8045             : 
    8046           4 :         cli_close(cli1, fnum1);
    8047             : 
    8048             :         /* Now create a hardlink. */
    8049           4 :         status = cli_posix_hardlink(cli1, fname, hname);
    8050           4 :         if (!NT_STATUS_IS_OK(status)) {
    8051           0 :                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
    8052           0 :                 goto out;
    8053             :         }
    8054             : 
    8055             :         /* Now create a symlink. */
    8056           4 :         status = cli_posix_symlink(cli1, fname, sname);
    8057           4 :         if (!NT_STATUS_IS_OK(status)) {
    8058           0 :                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
    8059           0 :                 goto out;
    8060             :         }
    8061             : 
    8062             :         /* Open the hardlink for read. */
    8063           4 :         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
    8064           4 :         if (!NT_STATUS_IS_OK(status)) {
    8065           0 :                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
    8066           0 :                 goto out;
    8067             :         }
    8068             : 
    8069           4 :         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
    8070           4 :         if (!NT_STATUS_IS_OK(status)) {
    8071           0 :                 printf("POSIX read of %s failed (%s)\n", hname,
    8072             :                        nt_errstr(status));
    8073           0 :                 goto out;
    8074           4 :         } else if (nread != 10) {
    8075           0 :                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
    8076             :                        hname, (unsigned long)nread, 10);
    8077           0 :                 goto out;
    8078             :         }
    8079             : 
    8080           4 :         if (memcmp(buf, "TEST DATA\n", 10)) {
    8081           0 :                 printf("invalid data read from hardlink\n");
    8082           0 :                 goto out;
    8083             :         }
    8084             : 
    8085             :         /* Do a POSIX lock/unlock. */
    8086           4 :         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
    8087           4 :         if (!NT_STATUS_IS_OK(status)) {
    8088           0 :                 printf("POSIX lock failed %s\n", nt_errstr(status));
    8089           0 :                 goto out;
    8090             :         }
    8091             : 
    8092             :         /* Punch a hole in the locked area. */
    8093           4 :         status = cli_posix_unlock(cli1, fnum1, 10, 80);
    8094           4 :         if (!NT_STATUS_IS_OK(status)) {
    8095           0 :                 printf("POSIX unlock failed %s\n", nt_errstr(status));
    8096           0 :                 goto out;
    8097             :         }
    8098             : 
    8099           4 :         cli_close(cli1, fnum1);
    8100             : 
    8101             :         /* Open the symlink for read - this should fail. A POSIX
    8102             :            client should not be doing opens on a symlink. */
    8103           4 :         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
    8104           4 :         if (NT_STATUS_IS_OK(status)) {
    8105           0 :                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
    8106           0 :                 goto out;
    8107             :         }
    8108           4 :         ok = check_both_error(
    8109             :                 __LINE__, status, ERRDOS, ERRbadpath,
    8110           4 :                 NT_STATUS_OBJECT_NAME_NOT_FOUND);
    8111           4 :         if (!ok) {
    8112           0 :                 printf("POSIX open of %s should have failed "
    8113             :                        "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
    8114             :                        "failed with %s instead.\n",
    8115             :                        sname, nt_errstr(status));
    8116           0 :                 goto out;
    8117             :         }
    8118             : 
    8119           4 :         status = cli_readlink(cli1, sname, talloc_tos(), &target, NULL, NULL);
    8120           4 :         if (!NT_STATUS_IS_OK(status)) {
    8121           0 :                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
    8122           0 :                 goto out;
    8123             :         }
    8124             : 
    8125           4 :         if (strcmp(target, fname) != 0) {
    8126           0 :                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
    8127             :                         sname, fname, target);
    8128           0 :                 goto out;
    8129             :         }
    8130             : 
    8131           4 :         status = cli_posix_rmdir(cli1, dname);
    8132           4 :         if (!NT_STATUS_IS_OK(status)) {
    8133           0 :                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
    8134           0 :                 goto out;
    8135             :         }
    8136             : 
    8137             :         /* Check directory opens with a specific permission. */
    8138           4 :         status = cli_posix_mkdir(cli1, dname, 0700);
    8139           4 :         if (!NT_STATUS_IS_OK(status)) {
    8140           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    8141           0 :                 goto out;
    8142             :         }
    8143             : 
    8144             :         /* Ensure st_mode == 0700 */
    8145           4 :         status = cli_posix_stat(cli1, dname, &sbuf);
    8146           4 :         if (!NT_STATUS_IS_OK(status)) {
    8147           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    8148           0 :                 goto out;
    8149             :         }
    8150             : 
    8151           4 :         if ((sbuf.st_ex_mode & 07777) != 0700) {
    8152           0 :                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
    8153           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    8154           0 :                 goto out;
    8155             :         }
    8156             : 
    8157             :         /*
    8158             :          * Now create a Windows file, and attempt a POSIX unlink.
    8159             :          * This should fail with a sharing violation but due to:
    8160             :          *
    8161             :          * [Bug 9571] Unlink after open causes smbd to panic
    8162             :          *
    8163             :          * ensure we've fixed the lock ordering violation.
    8164             :          */
    8165             : 
    8166           4 :         status = cli_ntcreate(cli1, fname_windows, 0,
    8167             :                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
    8168             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8169             :                         FILE_CREATE,
    8170             :                         0x0, 0x0, &fnum2, NULL);
    8171           4 :         if (!NT_STATUS_IS_OK(status)) {
    8172           0 :                 printf("Windows create of %s failed (%s)\n", fname_windows,
    8173             :                         nt_errstr(status));
    8174           0 :                 goto out;
    8175             :         }
    8176             : 
    8177             :         /* Now try posix_unlink. */
    8178           4 :         status = cli_posix_unlink(cli1, fname_windows);
    8179           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8180           0 :                 printf("POSIX unlink of %s should fail "
    8181             :                         "with NT_STATUS_SHARING_VIOLATION "
    8182             :                         "got %s instead !\n",
    8183             :                         fname_windows,
    8184             :                         nt_errstr(status));
    8185           0 :                 goto out;
    8186             :         }
    8187             : 
    8188           4 :         cli_close(cli1, fnum2);
    8189             : 
    8190           4 :         printf("Simple POSIX open test passed\n");
    8191           4 :         correct = true;
    8192             : 
    8193           4 :   out:
    8194             : 
    8195           4 :         if (fnum1 != (uint16_t)-1) {
    8196           4 :                 cli_close(cli1, fnum1);
    8197           4 :                 fnum1 = (uint16_t)-1;
    8198             :         }
    8199             : 
    8200           4 :         if (fnum2 != (uint16_t)-1) {
    8201           4 :                 cli_close(cli1, fnum2);
    8202           4 :                 fnum2 = (uint16_t)-1;
    8203             :         }
    8204             : 
    8205           4 :         cli_setatr(cli1, sname, 0, 0);
    8206           4 :         cli_posix_unlink(cli1, sname);
    8207           4 :         cli_setatr(cli1, hname, 0, 0);
    8208           4 :         cli_posix_unlink(cli1, hname);
    8209           4 :         cli_setatr(cli1, fname, 0, 0);
    8210           4 :         cli_posix_unlink(cli1, fname);
    8211           4 :         cli_setatr(cli1, dname, 0, 0);
    8212           4 :         cli_posix_rmdir(cli1, dname);
    8213           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    8214           4 :         cli_posix_unlink(cli1, fname_windows);
    8215             : 
    8216           4 :         if (!torture_close_connection(cli1)) {
    8217           0 :                 correct = false;
    8218             :         }
    8219             : 
    8220           4 :         return correct;
    8221             : }
    8222             : 
    8223             : /*
    8224             :   Test POSIX and Windows ACLs are rejected on symlinks.
    8225             :  */
    8226           4 : static bool run_acl_symlink_test(int dummy)
    8227             : {
    8228           0 :         static struct cli_state *cli;
    8229           4 :         const char *fname = "posix_file";
    8230           4 :         const char *sname = "posix_symlink";
    8231           4 :         uint16_t fnum = (uint16_t)-1;
    8232           4 :         bool correct = false;
    8233           0 :         NTSTATUS status;
    8234           4 :         char *posix_acl = NULL;
    8235           4 :         size_t posix_acl_len = 0;
    8236           4 :         char *posix_acl_sym = NULL;
    8237           4 :         size_t posix_acl_len_sym = 0;
    8238           4 :         struct security_descriptor *sd = NULL;
    8239           4 :         TALLOC_CTX *frame = NULL;
    8240             : 
    8241           4 :         frame = talloc_stackframe();
    8242             : 
    8243           4 :         printf("Starting acl symlink test\n");
    8244             : 
    8245           4 :         if (!torture_open_connection(&cli, 0)) {
    8246           0 :                 TALLOC_FREE(frame);
    8247           0 :                 return false;
    8248             :         }
    8249             : 
    8250           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8251             : 
    8252           4 :         status = torture_setup_unix_extensions(cli);
    8253           4 :         if (!NT_STATUS_IS_OK(status)) {
    8254           0 :                 TALLOC_FREE(frame);
    8255           0 :                 return false;
    8256             :         }
    8257             : 
    8258           4 :         cli_setatr(cli, fname, 0, 0);
    8259           4 :         cli_posix_unlink(cli, fname);
    8260           4 :         cli_setatr(cli, sname, 0, 0);
    8261           4 :         cli_posix_unlink(cli, sname);
    8262             : 
    8263           4 :         status = cli_ntcreate(cli,
    8264             :                         fname,
    8265             :                         0,
    8266             :                         READ_CONTROL_ACCESS,
    8267             :                         0,
    8268             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8269             :                         FILE_CREATE,
    8270             :                         0x0,
    8271             :                         0x0,
    8272             :                         &fnum,
    8273             :                         NULL);
    8274             : 
    8275           4 :         if (!NT_STATUS_IS_OK(status)) {
    8276           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8277             :                         fname,
    8278             :                         nt_errstr(status));
    8279           0 :                 goto out;
    8280             :         }
    8281             : 
    8282             :         /* Get the Windows ACL on the file. */
    8283           4 :         status = cli_query_secdesc(cli,
    8284             :                                 fnum,
    8285             :                                 frame,
    8286             :                                 &sd);
    8287           4 :         if (!NT_STATUS_IS_OK(status)) {
    8288           0 :                 printf("cli_query_secdesc failed (%s)\n",
    8289             :                         nt_errstr(status));
    8290           0 :                 goto out;
    8291             :         }
    8292             : 
    8293             :         /* Get the POSIX ACL on the file. */
    8294           4 :         status = cli_posix_getacl(cli,
    8295             :                                 fname,
    8296             :                                 frame,
    8297             :                                 &posix_acl_len,
    8298             :                                 &posix_acl);
    8299             : 
    8300           4 :         if (!NT_STATUS_IS_OK(status)) {
    8301           0 :                 printf("cli_posix_getacl failed (%s)\n",
    8302             :                         nt_errstr(status));
    8303           0 :                 goto out;
    8304             :         }
    8305             : 
    8306           4 :         status = cli_close(cli, fnum);
    8307           4 :         if (!NT_STATUS_IS_OK(status)) {
    8308           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8309           0 :                 goto out;
    8310             :         }
    8311           4 :         fnum = (uint16_t)-1;
    8312             : 
    8313             :         /* Now create a symlink. */
    8314           4 :         status = cli_posix_symlink(cli, fname, sname);
    8315           4 :         if (!NT_STATUS_IS_OK(status)) {
    8316           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8317             :                         sname,
    8318             :                         fname,
    8319             :                         nt_errstr(status));
    8320           0 :                 goto out;
    8321             :         }
    8322             : 
    8323             :         /* Open a handle on the symlink for SD set/get should fail. */
    8324           4 :         status = cli_ntcreate(cli,
    8325             :                         sname,
    8326             :                         0,
    8327             :                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
    8328             :                         0,
    8329             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8330             :                         FILE_OPEN,
    8331             :                         0x0,
    8332             :                         0x0,
    8333             :                         &fnum,
    8334             :                         NULL);
    8335             : 
    8336           4 :         if (NT_STATUS_IS_OK(status)) {
    8337           0 :                 printf("Symlink open for getsd/setsd of %s "
    8338             :                         "succeeded (should fail)\n",
    8339             :                         sname);
    8340           0 :                 goto out;
    8341             :         }
    8342             : 
    8343             :         /* Try a stat-open on the symlink, should also fail. */
    8344           4 :         status = cli_ntcreate(cli,
    8345             :                         sname,
    8346             :                         0,
    8347             :                         FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
    8348             :                         0,
    8349             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8350             :                         FILE_OPEN,
    8351             :                         0x0,
    8352             :                         0x0,
    8353             :                         &fnum,
    8354             :                         NULL);
    8355             : 
    8356           4 :         if (NT_STATUS_IS_OK(status)) {
    8357           0 :                 printf("Stat-open of symlink succeeded (should fail)\n");
    8358           0 :                 goto out;
    8359             :         }
    8360             : 
    8361             :         /* Get the POSIX ACL on the symlink pathname. Should fail. */
    8362           4 :         status = cli_posix_getacl(cli,
    8363             :                                 sname,
    8364             :                                 frame,
    8365             :                                 &posix_acl_len_sym,
    8366             :                                 &posix_acl_sym);
    8367             : 
    8368           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8369           0 :                 printf("cli_posix_getacl on a symlink gave %s. "
    8370             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8371             :                         nt_errstr(status));
    8372           0 :                 goto out;
    8373             :         }
    8374             : 
    8375             :         /* Set the POSIX ACL on the symlink pathname. Should fail. */
    8376           4 :         status = cli_posix_setacl(cli,
    8377             :                                 sname,
    8378             :                                 posix_acl,
    8379             :                                 posix_acl_len);
    8380             : 
    8381           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8382           0 :                 printf("cli_posix_setacl on a symlink gave %s. "
    8383             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8384             :                         nt_errstr(status));
    8385           0 :                 goto out;
    8386             :         }
    8387             : 
    8388           4 :         printf("ACL symlink test passed\n");
    8389           4 :         correct = true;
    8390             : 
    8391           4 :   out:
    8392             : 
    8393           4 :         if (fnum != (uint16_t)-1) {
    8394           0 :                 cli_close(cli, fnum);
    8395           0 :                 fnum = (uint16_t)-1;
    8396             :         }
    8397             : 
    8398           4 :         cli_setatr(cli, sname, 0, 0);
    8399           4 :         cli_posix_unlink(cli, sname);
    8400           4 :         cli_setatr(cli, fname, 0, 0);
    8401           4 :         cli_posix_unlink(cli, fname);
    8402             : 
    8403           4 :         if (!torture_close_connection(cli)) {
    8404           0 :                 correct = false;
    8405             :         }
    8406             : 
    8407           4 :         TALLOC_FREE(frame);
    8408           4 :         return correct;
    8409             : }
    8410             : 
    8411             : /*
    8412             :   Test POSIX can delete a file containing streams.
    8413             :  */
    8414           4 : static bool run_posix_stream_delete(int dummy)
    8415             : {
    8416           4 :         struct cli_state *cli1 = NULL;
    8417           4 :         struct cli_state *cli2 = NULL;
    8418           4 :         const char *fname = "streamfile";
    8419           4 :         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
    8420           4 :         uint16_t fnum1 = (uint16_t)-1;
    8421           4 :         bool correct = false;
    8422           0 :         NTSTATUS status;
    8423           4 :         TALLOC_CTX *frame = NULL;
    8424             : 
    8425           4 :         frame = talloc_stackframe();
    8426             : 
    8427           4 :         printf("Starting POSIX stream delete test\n");
    8428             : 
    8429           4 :         if (!torture_open_connection(&cli1, 0) ||
    8430           4 :                         !torture_open_connection(&cli2, 1)) {
    8431           0 :                 TALLOC_FREE(frame);
    8432           0 :                 return false;
    8433             :         }
    8434             : 
    8435           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8436           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    8437             : 
    8438           4 :         status = torture_setup_unix_extensions(cli2);
    8439           4 :         if (!NT_STATUS_IS_OK(status)) {
    8440           0 :                 goto out;
    8441             :         }
    8442             : 
    8443           4 :         cli_setatr(cli1, fname, 0, 0);
    8444           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8445             : 
    8446             :         /* Create the file. */
    8447           4 :         status = cli_ntcreate(cli1,
    8448             :                         fname,
    8449             :                         0,
    8450             :                         READ_CONTROL_ACCESS,
    8451             :                         0,
    8452             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8453             :                         FILE_CREATE,
    8454             :                         0x0,
    8455             :                         0x0,
    8456             :                         &fnum1,
    8457             :                         NULL);
    8458             : 
    8459           4 :         if (!NT_STATUS_IS_OK(status)) {
    8460           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8461             :                         fname,
    8462             :                         nt_errstr(status));
    8463           0 :                 goto out;
    8464             :         }
    8465             : 
    8466           4 :         status = cli_close(cli1, fnum1);
    8467           4 :         if (!NT_STATUS_IS_OK(status)) {
    8468           0 :                 printf("cli_close of %s failed (%s)\n",
    8469             :                         fname,
    8470             :                         nt_errstr(status));
    8471           0 :                 goto out;
    8472             :         }
    8473           4 :         fnum1 = (uint16_t)-1;
    8474             : 
    8475             :         /* Now create the stream. */
    8476           4 :         status = cli_ntcreate(cli1,
    8477             :                         stream_fname,
    8478             :                         0,
    8479             :                         FILE_WRITE_DATA,
    8480             :                         0,
    8481             :                         FILE_SHARE_READ|FILE_SHARE_WRITE,
    8482             :                         FILE_CREATE,
    8483             :                         0x0,
    8484             :                         0x0,
    8485             :                         &fnum1,
    8486             :                         NULL);
    8487             : 
    8488           4 :         if (!NT_STATUS_IS_OK(status)) {
    8489           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8490             :                         stream_fname,
    8491             :                         nt_errstr(status));
    8492           0 :                 goto out;
    8493             :         }
    8494             : 
    8495             :         /* Leave the stream handle open... */
    8496             : 
    8497             :         /* POSIX unlink should fail. */
    8498           4 :         status = cli_posix_unlink(cli2, fname);
    8499           4 :         if (NT_STATUS_IS_OK(status)) {
    8500           0 :                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
    8501             :                         fname);
    8502           0 :                 goto out;
    8503             :         }
    8504             : 
    8505           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8506           0 :                 printf("cli_posix_unlink of %s failed with (%s) "
    8507             :                         "should have been NT_STATUS_SHARING_VIOLATION\n",
    8508             :                         fname,
    8509             :                         nt_errstr(status));
    8510           0 :                 goto out;
    8511             :         }
    8512             : 
    8513             :         /* Close the stream handle. */
    8514           4 :         status = cli_close(cli1, fnum1);
    8515           4 :         if (!NT_STATUS_IS_OK(status)) {
    8516           0 :                 printf("cli_close of %s failed (%s)\n",
    8517             :                         stream_fname,
    8518             :                         nt_errstr(status));
    8519           0 :                 goto out;
    8520             :         }
    8521           4 :         fnum1 = (uint16_t)-1;
    8522             : 
    8523             :         /* POSIX unlink after stream handle closed should succeed. */
    8524           4 :         status = cli_posix_unlink(cli2, fname);
    8525           4 :         if (!NT_STATUS_IS_OK(status)) {
    8526           0 :                 printf("cli_posix_unlink of %s failed (%s)\n",
    8527             :                         fname,
    8528             :                         nt_errstr(status));
    8529           0 :                 goto out;
    8530             :         }
    8531             : 
    8532           4 :         printf("POSIX stream delete test passed\n");
    8533           4 :         correct = true;
    8534             : 
    8535           4 :   out:
    8536             : 
    8537           4 :         if (fnum1 != (uint16_t)-1) {
    8538           0 :                 cli_close(cli1, fnum1);
    8539           0 :                 fnum1 = (uint16_t)-1;
    8540             :         }
    8541             : 
    8542           4 :         cli_setatr(cli1, fname, 0, 0);
    8543           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8544             : 
    8545           4 :         if (!torture_close_connection(cli1)) {
    8546           0 :                 correct = false;
    8547             :         }
    8548           4 :         if (!torture_close_connection(cli2)) {
    8549           0 :                 correct = false;
    8550             :         }
    8551             : 
    8552           4 :         TALLOC_FREE(frame);
    8553           4 :         return correct;
    8554             : }
    8555             : 
    8556             : /*
    8557             :   Test setting EA's are rejected on symlinks.
    8558             :  */
    8559           4 : static bool run_ea_symlink_test(int dummy)
    8560             : {
    8561           0 :         static struct cli_state *cli;
    8562           4 :         const char *fname = "posix_file_ea";
    8563           4 :         const char *sname = "posix_symlink_ea";
    8564           4 :         const char *ea_name = "testea_name";
    8565           4 :         const char *ea_value = "testea_value";
    8566           4 :         uint16_t fnum = (uint16_t)-1;
    8567           4 :         bool correct = false;
    8568           0 :         NTSTATUS status;
    8569           0 :         size_t i, num_eas;
    8570           4 :         struct ea_struct *eas = NULL;
    8571           4 :         TALLOC_CTX *frame = NULL;
    8572             : 
    8573           4 :         frame = talloc_stackframe();
    8574             : 
    8575           4 :         printf("Starting EA symlink test\n");
    8576             : 
    8577           4 :         if (!torture_open_connection(&cli, 0)) {
    8578           0 :                 TALLOC_FREE(frame);
    8579           0 :                 return false;
    8580             :         }
    8581             : 
    8582           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8583             : 
    8584           4 :         status = torture_setup_unix_extensions(cli);
    8585           4 :         if (!NT_STATUS_IS_OK(status)) {
    8586           0 :                 TALLOC_FREE(frame);
    8587           0 :                 return false;
    8588             :         }
    8589             : 
    8590           4 :         cli_setatr(cli, fname, 0, 0);
    8591           4 :         cli_posix_unlink(cli, fname);
    8592           4 :         cli_setatr(cli, sname, 0, 0);
    8593           4 :         cli_posix_unlink(cli, sname);
    8594             : 
    8595           4 :         status = cli_ntcreate(cli,
    8596             :                         fname,
    8597             :                         0,
    8598             :                         READ_CONTROL_ACCESS,
    8599             :                         0,
    8600             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8601             :                         FILE_CREATE,
    8602             :                         0x0,
    8603             :                         0x0,
    8604             :                         &fnum,
    8605             :                         NULL);
    8606             : 
    8607           4 :         if (!NT_STATUS_IS_OK(status)) {
    8608           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8609             :                         fname,
    8610             :                         nt_errstr(status));
    8611           0 :                 goto out;
    8612             :         }
    8613             : 
    8614           4 :         status = cli_close(cli, fnum);
    8615           4 :         if (!NT_STATUS_IS_OK(status)) {
    8616           0 :                 printf("close failed (%s)\n",
    8617             :                         nt_errstr(status));
    8618           0 :                 goto out;
    8619             :         }
    8620           4 :         fnum = (uint16_t)-1;
    8621             : 
    8622             :         /* Set an EA on the path. */
    8623           4 :         status = cli_set_ea_path(cli,
    8624             :                                 fname,
    8625             :                                 ea_name,
    8626             :                                 ea_value,
    8627           4 :                                 strlen(ea_value)+1);
    8628             : 
    8629           4 :         if (!NT_STATUS_IS_OK(status)) {
    8630           0 :                 printf("cli_set_ea_path failed (%s)\n",
    8631             :                         nt_errstr(status));
    8632           0 :                 goto out;
    8633             :         }
    8634             : 
    8635             :         /* Now create a symlink. */
    8636           4 :         status = cli_posix_symlink(cli, fname, sname);
    8637           4 :         if (!NT_STATUS_IS_OK(status)) {
    8638           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8639             :                         sname,
    8640             :                         fname,
    8641             :                         nt_errstr(status));
    8642           0 :                 goto out;
    8643             :         }
    8644             : 
    8645             :         /* Get the EA list on the path. Should return value set. */
    8646           4 :         status = cli_get_ea_list_path(cli,
    8647             :                                 fname,
    8648             :                                 frame,
    8649             :                                 &num_eas,
    8650             :                                 &eas);
    8651             : 
    8652           4 :         if (!NT_STATUS_IS_OK(status)) {
    8653           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8654             :                         nt_errstr(status));
    8655           0 :                 goto out;
    8656             :         }
    8657             : 
    8658             :         /* Ensure the EA we set is there. */
    8659           4 :         for (i=0; i<num_eas; i++) {
    8660           4 :                 if (strcmp(eas[i].name, ea_name) == 0 &&
    8661           4 :                                 eas[i].value.length == strlen(ea_value)+1 &&
    8662           4 :                                 memcmp(eas[i].value.data,
    8663             :                                         ea_value,
    8664           4 :                                         eas[i].value.length) == 0) {
    8665           4 :                         break;
    8666             :                 }
    8667             :         }
    8668             : 
    8669           4 :         if (i == num_eas) {
    8670           0 :                 printf("Didn't find EA on pathname %s\n",
    8671             :                         fname);
    8672           0 :                 goto out;
    8673             :         }
    8674             : 
    8675           4 :         num_eas = 0;
    8676           4 :         TALLOC_FREE(eas);
    8677             : 
    8678             :         /* Get the EA list on the symlink. Should return empty list. */
    8679           4 :         status = cli_get_ea_list_path(cli,
    8680             :                                 sname,
    8681             :                                 frame,
    8682             :                                 &num_eas,
    8683             :                                 &eas);
    8684             : 
    8685           4 :         if (!NT_STATUS_IS_OK(status)) {
    8686           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8687             :                         nt_errstr(status));
    8688           0 :                 goto out;
    8689             :         }
    8690             : 
    8691           4 :         if (num_eas != 0) {
    8692           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8693             :                         nt_errstr(status));
    8694           0 :                 goto out;
    8695             :         }
    8696             : 
    8697             :         /* Set an EA on the symlink. Should fail. */
    8698           4 :         status = cli_set_ea_path(cli,
    8699             :                                 sname,
    8700             :                                 ea_name,
    8701             :                                 ea_value,
    8702           4 :                                 strlen(ea_value)+1);
    8703             : 
    8704           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8705           0 :                 printf("cli_set_ea_path on a symlink gave %s. "
    8706             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8707             :                         nt_errstr(status));
    8708           0 :                 goto out;
    8709             :         }
    8710             : 
    8711           4 :         printf("EA symlink test passed\n");
    8712           4 :         correct = true;
    8713             : 
    8714           4 :   out:
    8715             : 
    8716           4 :         if (fnum != (uint16_t)-1) {
    8717           0 :                 cli_close(cli, fnum);
    8718           0 :                 fnum = (uint16_t)-1;
    8719             :         }
    8720             : 
    8721           4 :         cli_setatr(cli, sname, 0, 0);
    8722           4 :         cli_posix_unlink(cli, sname);
    8723           4 :         cli_setatr(cli, fname, 0, 0);
    8724           4 :         cli_posix_unlink(cli, fname);
    8725             : 
    8726           4 :         if (!torture_close_connection(cli)) {
    8727           0 :                 correct = false;
    8728             :         }
    8729             : 
    8730           4 :         TALLOC_FREE(frame);
    8731           4 :         return correct;
    8732             : }
    8733             : 
    8734             : /*
    8735             :   Test POSIX locks are OFD-locks.
    8736             :  */
    8737           4 : static bool run_posix_ofd_lock_test(int dummy)
    8738             : {
    8739           0 :         static struct cli_state *cli;
    8740           4 :         const char *fname = "posix_file";
    8741           4 :         uint16_t fnum1 = (uint16_t)-1;
    8742           4 :         uint16_t fnum2 = (uint16_t)-1;
    8743           4 :         bool correct = false;
    8744           0 :         NTSTATUS status;
    8745           4 :         TALLOC_CTX *frame = NULL;
    8746             : 
    8747           4 :         frame = talloc_stackframe();
    8748             : 
    8749           4 :         printf("Starting POSIX ofd-lock test\n");
    8750             : 
    8751           4 :         if (!torture_open_connection(&cli, 0)) {
    8752           0 :                 TALLOC_FREE(frame);
    8753           0 :                 return false;
    8754             :         }
    8755             : 
    8756           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8757             : 
    8758           4 :         status = torture_setup_unix_extensions(cli);
    8759           4 :         if (!NT_STATUS_IS_OK(status)) {
    8760           0 :                 TALLOC_FREE(frame);
    8761           0 :                 return false;
    8762             :         }
    8763             : 
    8764           4 :         cli_setatr(cli, fname, 0, 0);
    8765           4 :         cli_posix_unlink(cli, fname);
    8766             : 
    8767             :         /* Open the file twice. */
    8768           4 :         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
    8769             :                                 0600, &fnum1);
    8770           4 :         if (!NT_STATUS_IS_OK(status)) {
    8771           0 :                 printf("First POSIX open of %s failed\n", fname);
    8772           0 :                 goto out;
    8773             :         }
    8774             : 
    8775           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
    8776           4 :         if (!NT_STATUS_IS_OK(status)) {
    8777           0 :                 printf("First POSIX open of %s failed\n", fname);
    8778           0 :                 goto out;
    8779             :         }
    8780             : 
    8781             :         /* Set a 0-50 lock on fnum1. */
    8782           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8783           4 :         if (!NT_STATUS_IS_OK(status)) {
    8784           0 :                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
    8785           0 :                 goto out;
    8786             :         }
    8787             : 
    8788             :         /* Set a 60-100 lock on fnum2. */
    8789           4 :         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
    8790           4 :         if (!NT_STATUS_IS_OK(status)) {
    8791           0 :                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
    8792           0 :                 goto out;
    8793             :         }
    8794             : 
    8795             :         /* close fnum1 - 0-50 lock should go away. */
    8796           4 :         status = cli_close(cli, fnum1);
    8797           4 :         if (!NT_STATUS_IS_OK(status)) {
    8798           0 :                 printf("close failed (%s)\n",
    8799             :                         nt_errstr(status));
    8800           0 :                 goto out;
    8801             :         }
    8802           4 :         fnum1 = (uint16_t)-1;
    8803             : 
    8804             :         /* Change the lock context. */
    8805           4 :         cli_setpid(cli, cli_getpid(cli) + 1);
    8806             : 
    8807             :         /* Re-open fnum1. */
    8808           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
    8809           4 :         if (!NT_STATUS_IS_OK(status)) {
    8810           0 :                 printf("Third POSIX open of %s failed\n", fname);
    8811           0 :                 goto out;
    8812             :         }
    8813             : 
    8814             :         /* 60-100 lock should still be there. */
    8815           4 :         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
    8816           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    8817           0 :                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
    8818           0 :                 goto out;
    8819             :         }
    8820             : 
    8821             :         /* 0-50 lock should be gone. */
    8822           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8823           4 :         if (!NT_STATUS_IS_OK(status)) {
    8824           0 :                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
    8825           0 :                 goto out;
    8826             :         }
    8827             : 
    8828           4 :         printf("POSIX OFD lock test passed\n");
    8829           4 :         correct = true;
    8830             : 
    8831           4 :   out:
    8832             : 
    8833           4 :         if (fnum1 != (uint16_t)-1) {
    8834           4 :                 cli_close(cli, fnum1);
    8835           4 :                 fnum1 = (uint16_t)-1;
    8836             :         }
    8837           4 :         if (fnum2 != (uint16_t)-1) {
    8838           4 :                 cli_close(cli, fnum2);
    8839           4 :                 fnum2 = (uint16_t)-1;
    8840             :         }
    8841             : 
    8842           4 :         cli_setatr(cli, fname, 0, 0);
    8843           4 :         cli_posix_unlink(cli, fname);
    8844             : 
    8845           4 :         if (!torture_close_connection(cli)) {
    8846           0 :                 correct = false;
    8847             :         }
    8848             : 
    8849           4 :         TALLOC_FREE(frame);
    8850           4 :         return correct;
    8851             : }
    8852             : 
    8853             : struct posix_blocking_state {
    8854             :         struct tevent_context *ev;
    8855             :         struct cli_state *cli1;
    8856             :         uint16_t fnum1;
    8857             :         struct cli_state *cli2;
    8858             :         uint16_t fnum2;
    8859             :         bool gotblocked;
    8860             :         bool gotecho;
    8861             : };
    8862             : 
    8863             : static void posix_blocking_locked(struct tevent_req *subreq);
    8864             : static void posix_blocking_gotblocked(struct tevent_req *subreq);
    8865             : static void posix_blocking_gotecho(struct tevent_req *subreq);
    8866             : static void posix_blocking_unlocked(struct tevent_req *subreq);
    8867             : 
    8868           4 : static struct tevent_req *posix_blocking_send(
    8869             :         TALLOC_CTX *mem_ctx,
    8870             :         struct tevent_context *ev,
    8871             :         struct cli_state *cli1,
    8872             :         uint16_t fnum1,
    8873             :         struct cli_state *cli2,
    8874             :         uint16_t fnum2)
    8875             : {
    8876           4 :         struct tevent_req *req = NULL, *subreq = NULL;
    8877           4 :         struct posix_blocking_state *state = NULL;
    8878             : 
    8879           4 :         req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
    8880           4 :         if (req == NULL) {
    8881           0 :                 return NULL;
    8882             :         }
    8883           4 :         state->ev = ev;
    8884           4 :         state->cli1 = cli1;
    8885           4 :         state->fnum1 = fnum1;
    8886           4 :         state->cli2 = cli2;
    8887           4 :         state->fnum2 = fnum2;
    8888             : 
    8889           4 :         subreq = cli_posix_lock_send(
    8890             :                 state,
    8891           4 :                 state->ev,
    8892           4 :                 state->cli1,
    8893           4 :                 state->fnum1,
    8894             :                 0,
    8895             :                 1,
    8896             :                 false,
    8897             :                 WRITE_LOCK);
    8898           4 :         if (tevent_req_nomem(subreq, req)) {
    8899           0 :                 return tevent_req_post(req, ev);
    8900             :         }
    8901           4 :         tevent_req_set_callback(subreq, posix_blocking_locked, req);
    8902           4 :         return req;
    8903             : }
    8904             : 
    8905           4 : static void posix_blocking_locked(struct tevent_req *subreq)
    8906             : {
    8907           4 :         struct tevent_req *req = tevent_req_callback_data(
    8908             :                 subreq, struct tevent_req);
    8909           4 :         struct posix_blocking_state *state = tevent_req_data(
    8910             :                 req, struct posix_blocking_state);
    8911           0 :         NTSTATUS status;
    8912             : 
    8913           4 :         status = cli_posix_lock_recv(subreq);
    8914           4 :         TALLOC_FREE(subreq);
    8915           4 :         if (tevent_req_nterror(req, status)) {
    8916           0 :                 return;
    8917             :         }
    8918             : 
    8919           4 :         subreq = cli_posix_lock_send(
    8920             :                 state,
    8921             :                 state->ev,
    8922             :                 state->cli2,
    8923           4 :                 state->fnum2,
    8924             :                 0,
    8925             :                 1,
    8926             :                 true,
    8927             :                 WRITE_LOCK);
    8928           4 :         if (tevent_req_nomem(subreq, req)) {
    8929           0 :                 return;
    8930             :         }
    8931           4 :         tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
    8932             : 
    8933             :         /* Make sure the blocking request is delivered */
    8934           4 :         subreq = cli_echo_send(
    8935             :                 state,
    8936             :                 state->ev,
    8937             :                 state->cli2,
    8938             :                 1,
    8939           4 :                 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
    8940           4 :         if (tevent_req_nomem(subreq, req)) {
    8941           0 :                 return;
    8942             :         }
    8943           4 :         tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
    8944             : }
    8945             : 
    8946           4 : static void posix_blocking_gotblocked(struct tevent_req *subreq)
    8947             : {
    8948           4 :         struct tevent_req *req = tevent_req_callback_data(
    8949             :                 subreq, struct tevent_req);
    8950           4 :         struct posix_blocking_state *state = tevent_req_data(
    8951             :                 req, struct posix_blocking_state);
    8952           0 :         NTSTATUS status;
    8953             : 
    8954           4 :         status = cli_posix_lock_recv(subreq);
    8955           4 :         TALLOC_FREE(subreq);
    8956           4 :         if (tevent_req_nterror(req, status)) {
    8957           0 :                 return;
    8958             :         }
    8959           4 :         if (!state->gotecho) {
    8960           0 :                 printf("blocked req got through before echo\n");
    8961           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8962           0 :                 return;
    8963             :         }
    8964           4 :         tevent_req_done(req);
    8965             : }
    8966             : 
    8967           4 : static void posix_blocking_gotecho(struct tevent_req *subreq)
    8968             : {
    8969           4 :         struct tevent_req *req = tevent_req_callback_data(
    8970             :                 subreq, struct tevent_req);
    8971           4 :         struct posix_blocking_state *state = tevent_req_data(
    8972             :                 req, struct posix_blocking_state);
    8973           0 :         NTSTATUS status;
    8974             : 
    8975           4 :         status = cli_echo_recv(subreq);
    8976           4 :         TALLOC_FREE(subreq);
    8977           4 :         if (tevent_req_nterror(req, status)) {
    8978           0 :                 return;
    8979             :         }
    8980           4 :         if (state->gotblocked) {
    8981           0 :                 printf("blocked req got through before echo\n");
    8982           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8983           0 :                 return;
    8984             :         }
    8985           4 :         state->gotecho = true;
    8986             : 
    8987           4 :         subreq = cli_posix_lock_send(
    8988             :                 state,
    8989             :                 state->ev,
    8990             :                 state->cli1,
    8991           4 :                 state->fnum1,
    8992             :                 0,
    8993             :                 1,
    8994             :                 false,
    8995             :                 UNLOCK_LOCK);
    8996           4 :         if (tevent_req_nomem(subreq, req)) {
    8997           0 :                 return;
    8998             :         }
    8999           4 :         tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
    9000             : }
    9001             : 
    9002           4 : static void posix_blocking_unlocked(struct tevent_req *subreq)
    9003             : {
    9004           4 :         struct tevent_req *req = tevent_req_callback_data(
    9005             :                 subreq, struct tevent_req);
    9006           0 :         NTSTATUS status;
    9007             : 
    9008           4 :         status = cli_posix_lock_recv(subreq);
    9009           4 :         TALLOC_FREE(subreq);
    9010           4 :         if (tevent_req_nterror(req, status)) {
    9011           0 :                 return;
    9012             :         }
    9013             :         /* tevent_req_done in posix_blocking_gotlocked */
    9014             : }
    9015             : 
    9016           4 : static NTSTATUS posix_blocking_recv(struct tevent_req *req)
    9017             : {
    9018           4 :         return tevent_req_simple_recv_ntstatus(req);
    9019             : }
    9020             : 
    9021           4 : static bool run_posix_blocking_lock(int dummy)
    9022             : {
    9023           4 :         struct tevent_context *ev = NULL;
    9024           4 :         struct cli_state *cli1 = NULL, *cli2 = NULL;
    9025           4 :         const char *fname = "posix_blocking";
    9026           4 :         uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
    9027           4 :         struct tevent_req *req = NULL;
    9028           0 :         NTSTATUS status;
    9029           4 :         bool ret = false;
    9030           0 :         bool ok;
    9031             : 
    9032           4 :         printf("Starting posix blocking lock test\n");
    9033             : 
    9034           4 :         ev = samba_tevent_context_init(NULL);
    9035           4 :         if (ev == NULL) {
    9036           0 :                 return false;
    9037             :         }
    9038             : 
    9039           4 :         ok = torture_open_connection(&cli1, 0);
    9040           4 :         if (!ok) {
    9041           0 :                 goto fail;
    9042             :         }
    9043           4 :         ok = torture_open_connection(&cli2, 0);
    9044           4 :         if (!ok) {
    9045           0 :                 goto fail;
    9046             :         }
    9047             : 
    9048           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9049             : 
    9050           4 :         status = torture_setup_unix_extensions(cli1);
    9051           4 :         if (!NT_STATUS_IS_OK(status)) {
    9052           0 :                 return false;
    9053             :         }
    9054             : 
    9055           4 :         status = torture_setup_unix_extensions(cli2);
    9056           4 :         if (!NT_STATUS_IS_OK(status)) {
    9057           0 :                 return false;
    9058             :         }
    9059             : 
    9060           4 :         cli_setatr(cli1, fname, 0, 0);
    9061           4 :         cli_posix_unlink(cli1, fname);
    9062             : 
    9063           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    9064             :                                 0600, &fnum1);
    9065           4 :         if (!NT_STATUS_IS_OK(status)) {
    9066           0 :                 printf("First POSIX open of %s failed: %s\n",
    9067             :                        fname,
    9068             :                        nt_errstr(status));
    9069           0 :                 goto fail;
    9070             :         }
    9071             : 
    9072           4 :         status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
    9073           4 :         if (!NT_STATUS_IS_OK(status)) {
    9074           0 :                 printf("Second POSIX open of %s failed: %s\n",
    9075             :                        fname,
    9076             :                        nt_errstr(status));
    9077           0 :                 goto fail;
    9078             :         }
    9079             : 
    9080           4 :         req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
    9081           4 :         if (req == NULL) {
    9082           0 :                 printf("cli_posix_blocking failed\n");
    9083           0 :                 goto fail;
    9084             :         }
    9085             : 
    9086           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    9087           4 :         if (!ok) {
    9088           0 :                 printf("tevent_req_poll_ntstatus failed: %s\n",
    9089             :                        nt_errstr(status));
    9090           0 :                 goto fail;
    9091             :         }
    9092           4 :         status = posix_blocking_recv(req);
    9093           4 :         TALLOC_FREE(req);
    9094           4 :         if (!NT_STATUS_IS_OK(status)) {
    9095           0 :                 printf("posix_blocking_recv returned %s\n",
    9096             :                        nt_errstr(status));
    9097           0 :                 goto fail;
    9098             :         }
    9099             : 
    9100           4 :         ret = true;
    9101           4 : fail:
    9102             : 
    9103           4 :         if (fnum1 != UINT16_MAX) {
    9104           4 :                 cli_close(cli1, fnum1);
    9105           4 :                 fnum1 = UINT16_MAX;
    9106             :         }
    9107           4 :         if (fnum2 != UINT16_MAX) {
    9108           4 :                 cli_close(cli2, fnum2);
    9109           4 :                 fnum2 = UINT16_MAX;
    9110             :         }
    9111             : 
    9112           4 :         if (cli1 != NULL) {
    9113           4 :                 cli_setatr(cli1, fname, 0, 0);
    9114           4 :                 cli_posix_unlink(cli1, fname);
    9115             :         }
    9116             : 
    9117           4 :         ok = true;
    9118             : 
    9119           4 :         if (cli1 != NULL) {
    9120           4 :                 ok &= torture_close_connection(cli1);
    9121           4 :                 cli1 = NULL;
    9122             :         }
    9123           4 :         if (cli2 != NULL) {
    9124           4 :                 ok &= torture_close_connection(cli2);
    9125           4 :                 cli2 = NULL;
    9126             :         }
    9127             : 
    9128           4 :         if (!ok) {
    9129           0 :                 ret = false;
    9130             :         }
    9131           4 :         TALLOC_FREE(ev);
    9132           4 :         return ret;
    9133             : }
    9134             : 
    9135             : /*
    9136             :   Test POSIX mkdir is case-sensitive.
    9137             :  */
    9138           4 : static bool run_posix_mkdir_test(int dummy)
    9139             : {
    9140           0 :         static struct cli_state *cli;
    9141           4 :         const char *fname_foo = "POSIX_foo";
    9142           4 :         const char *fname_foo_Foo = "POSIX_foo/Foo";
    9143           4 :         const char *fname_foo_foo = "POSIX_foo/foo";
    9144           4 :         const char *fname_Foo = "POSIX_Foo";
    9145           4 :         const char *fname_Foo_Foo = "POSIX_Foo/Foo";
    9146           4 :         const char *fname_Foo_foo = "POSIX_Foo/foo";
    9147           4 :         bool correct = false;
    9148           0 :         NTSTATUS status;
    9149           4 :         TALLOC_CTX *frame = NULL;
    9150           4 :         uint16_t fnum = (uint16_t)-1;
    9151             : 
    9152           4 :         frame = talloc_stackframe();
    9153             : 
    9154           4 :         printf("Starting POSIX mkdir test\n");
    9155             : 
    9156           4 :         if (!torture_open_connection(&cli, 0)) {
    9157           0 :                 TALLOC_FREE(frame);
    9158           0 :                 return false;
    9159             :         }
    9160             : 
    9161           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9162             : 
    9163           4 :         status = torture_setup_unix_extensions(cli);
    9164           4 :         if (!NT_STATUS_IS_OK(status)) {
    9165           0 :                 TALLOC_FREE(frame);
    9166           0 :                 return false;
    9167             :         }
    9168             : 
    9169           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9170           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9171           4 :         cli_posix_rmdir(cli, fname_foo);
    9172             : 
    9173           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9174           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9175           4 :         cli_posix_rmdir(cli, fname_Foo);
    9176             : 
    9177             :         /*
    9178             :          * Create a file POSIX_foo then try
    9179             :          * and use it in a directory path by
    9180             :          * doing mkdir POSIX_foo/bar.
    9181             :          * The mkdir should fail with
    9182             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND
    9183             :          */
    9184             : 
    9185           4 :         status = cli_posix_open(cli,
    9186             :                         fname_foo,
    9187             :                         O_RDWR|O_CREAT,
    9188             :                         0666,
    9189             :                         &fnum);
    9190           4 :         if (!NT_STATUS_IS_OK(status)) {
    9191           0 :                 printf("cli_posix_open of %s failed error %s\n",
    9192             :                         fname_foo,
    9193             :                         nt_errstr(status));
    9194           0 :                 goto out;
    9195             :         }
    9196             : 
    9197           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9198           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9199           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9200             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9201             :                         "%s instead\n",
    9202             :                         fname_foo_foo,
    9203             :                         nt_errstr(status));
    9204           0 :                 goto out;
    9205             :         }
    9206             : 
    9207           4 :         status = cli_close(cli, fnum);
    9208           4 :         if (!NT_STATUS_IS_OK(status)) {
    9209           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    9210           0 :                 goto out;
    9211             :         }
    9212           4 :         fnum = (uint16_t)-1;
    9213             : 
    9214           4 :         status = cli_posix_unlink(cli, fname_foo);
    9215           4 :         if (!NT_STATUS_IS_OK(status)) {
    9216           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
    9217             :                         fname_foo,
    9218             :                         nt_errstr(status));
    9219           0 :                 goto out;
    9220             :         }
    9221             : 
    9222             :         /*
    9223             :          * Now we've deleted everything, posix_mkdir, posix_rmdir,
    9224             :          * posix_open, posix_unlink, on
    9225             :          * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
    9226             :          * not silently create POSIX_foo/foo.
    9227             :          */
    9228             : 
    9229           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9230           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9231           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9232             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9233             :                         "%s instead\n",
    9234             :                         fname_foo_foo,
    9235             :                         nt_errstr(status));
    9236           0 :                 goto out;
    9237             :         }
    9238             : 
    9239           4 :         status = cli_posix_rmdir(cli, fname_foo_foo);
    9240           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9241           0 :                 printf("cli_posix_rmdir of %s should fail with "
    9242             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9243             :                         "%s instead\n",
    9244             :                         fname_foo_foo,
    9245             :                         nt_errstr(status));
    9246           0 :                 goto out;
    9247             :         }
    9248             : 
    9249           4 :         status = cli_posix_open(cli,
    9250             :                         fname_foo_foo,
    9251             :                         O_RDWR|O_CREAT,
    9252             :                         0666,
    9253             :                         &fnum);
    9254           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9255           0 :                 printf("cli_posix_open of %s should fail with "
    9256             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9257             :                         "%s instead\n",
    9258             :                         fname_foo_foo,
    9259             :                         nt_errstr(status));
    9260           0 :                 goto out;
    9261             :         }
    9262             : 
    9263           4 :         status = cli_posix_unlink(cli, fname_foo_foo);
    9264           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9265           0 :                 printf("cli_posix_unlink of %s should fail with "
    9266             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9267             :                         "%s instead\n",
    9268             :                         fname_foo_foo,
    9269             :                         nt_errstr(status));
    9270           0 :                 goto out;
    9271             :         }
    9272             : 
    9273           4 :         status = cli_posix_mkdir(cli, fname_foo, 0777);
    9274           4 :         if (!NT_STATUS_IS_OK(status)) {
    9275           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo);
    9276           0 :                 goto out;
    9277             :         }
    9278             : 
    9279           4 :         status = cli_posix_mkdir(cli, fname_Foo, 0777);
    9280           4 :         if (!NT_STATUS_IS_OK(status)) {
    9281           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
    9282           0 :                 goto out;
    9283             :         }
    9284             : 
    9285           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9286           4 :         if (!NT_STATUS_IS_OK(status)) {
    9287           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
    9288           0 :                 goto out;
    9289             :         }
    9290             : 
    9291           4 :         status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
    9292           4 :         if (!NT_STATUS_IS_OK(status)) {
    9293           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
    9294           0 :                 goto out;
    9295             :         }
    9296             : 
    9297           4 :         status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
    9298           4 :         if (!NT_STATUS_IS_OK(status)) {
    9299           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
    9300           0 :                 goto out;
    9301             :         }
    9302             : 
    9303           4 :         status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
    9304           4 :         if (!NT_STATUS_IS_OK(status)) {
    9305           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
    9306           0 :                 goto out;
    9307             :         }
    9308             : 
    9309           4 :         printf("POSIX mkdir test passed\n");
    9310           4 :         correct = true;
    9311             : 
    9312           4 :   out:
    9313             : 
    9314           4 :         if (fnum != (uint16_t)-1) {
    9315           0 :                 cli_close(cli, fnum);
    9316           0 :                 fnum = (uint16_t)-1;
    9317             :         }
    9318             : 
    9319           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9320           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9321           4 :         cli_posix_rmdir(cli, fname_foo);
    9322             : 
    9323           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9324           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9325           4 :         cli_posix_rmdir(cli, fname_Foo);
    9326             : 
    9327           4 :         if (!torture_close_connection(cli)) {
    9328           0 :                 correct = false;
    9329             :         }
    9330             : 
    9331           4 :         TALLOC_FREE(frame);
    9332           4 :         return correct;
    9333             : }
    9334             : 
    9335             : struct posix_acl_oplock_state {
    9336             :         struct tevent_context *ev;
    9337             :         struct cli_state *cli;
    9338             :         bool *got_break;
    9339             :         bool *acl_ret;
    9340             :         NTSTATUS status;
    9341             : };
    9342             : 
    9343           4 : static void posix_acl_oplock_got_break(struct tevent_req *req)
    9344             : {
    9345           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9346             :                 req, struct posix_acl_oplock_state);
    9347           0 :         uint16_t fnum;
    9348           0 :         uint8_t level;
    9349           0 :         NTSTATUS status;
    9350             : 
    9351           4 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    9352           4 :         TALLOC_FREE(req);
    9353           4 :         if (!NT_STATUS_IS_OK(status)) {
    9354           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    9355             :                        nt_errstr(status));
    9356           0 :                 return;
    9357             :         }
    9358           4 :         *state->got_break = true;
    9359             : 
    9360           4 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    9361             :                                   NO_OPLOCK);
    9362           4 :         if (req == NULL) {
    9363           0 :                 printf("cli_oplock_ack_send failed\n");
    9364           0 :                 return;
    9365             :         }
    9366             : }
    9367             : 
    9368           4 : static void posix_acl_oplock_got_acl(struct tevent_req *req)
    9369             : {
    9370           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9371             :                 req, struct posix_acl_oplock_state);
    9372           4 :         size_t ret_size = 0;
    9373           4 :         char *ret_data = NULL;
    9374             : 
    9375           4 :         state->status = cli_posix_getacl_recv(req,
    9376             :                         state,
    9377             :                         &ret_size,
    9378             :                         &ret_data);
    9379             : 
    9380           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9381           0 :                 printf("cli_posix_getacl_recv returned %s\n",
    9382             :                         nt_errstr(state->status));
    9383             :         }
    9384           4 :         *state->acl_ret = true;
    9385           4 : }
    9386             : 
    9387           4 : static bool run_posix_acl_oplock_test(int dummy)
    9388             : {
    9389           0 :         struct tevent_context *ev;
    9390           0 :         struct cli_state *cli1, *cli2;
    9391           0 :         struct tevent_req *oplock_req, *getacl_req;
    9392           4 :         const char *fname = "posix_acl_oplock";
    9393           0 :         uint16_t fnum;
    9394           4 :         int saved_use_oplocks = use_oplocks;
    9395           0 :         NTSTATUS status;
    9396           4 :         bool correct = true;
    9397           4 :         bool got_break = false;
    9398           4 :         bool acl_ret = false;
    9399             : 
    9400           0 :         struct posix_acl_oplock_state *state;
    9401             : 
    9402           4 :         printf("starting posix_acl_oplock test\n");
    9403             : 
    9404           4 :         if (!torture_open_connection(&cli1, 0)) {
    9405           0 :                 use_level_II_oplocks = false;
    9406           0 :                 use_oplocks = saved_use_oplocks;
    9407           0 :                 return false;
    9408             :         }
    9409             : 
    9410           4 :         if (!torture_open_connection(&cli2, 1)) {
    9411           0 :                 use_level_II_oplocks = false;
    9412           0 :                 use_oplocks = saved_use_oplocks;
    9413           0 :                 return false;
    9414             :         }
    9415             : 
    9416             :         /* Setup posix on cli2 only. */
    9417           4 :         status = torture_setup_unix_extensions(cli2);
    9418           4 :         if (!NT_STATUS_IS_OK(status)) {
    9419           0 :                 return false;
    9420             :         }
    9421             : 
    9422           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9423           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    9424             : 
    9425           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9426             : 
    9427             :         /* Create the file on the Windows connection. */
    9428           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    9429             :                           &fnum);
    9430           4 :         if (!NT_STATUS_IS_OK(status)) {
    9431           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9432           0 :                 return false;
    9433             :         }
    9434             : 
    9435           4 :         status = cli_close(cli1, fnum);
    9436           4 :         if (!NT_STATUS_IS_OK(status)) {
    9437           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    9438           0 :                 return false;
    9439             :         }
    9440             : 
    9441           4 :         cli1->use_oplocks = true;
    9442             : 
    9443             :         /* Open with oplock. */
    9444           4 :         status = cli_ntcreate(cli1,
    9445             :                         fname,
    9446             :                         0,
    9447             :                         FILE_READ_DATA,
    9448             :                         FILE_ATTRIBUTE_NORMAL,
    9449             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    9450             :                         FILE_OPEN,
    9451             :                         0,
    9452             :                         0,
    9453             :                         &fnum,
    9454             :                         NULL);
    9455             : 
    9456           4 :         if (!NT_STATUS_IS_OK(status)) {
    9457           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9458           0 :                 return false;
    9459             :         }
    9460             : 
    9461           4 :         ev = samba_tevent_context_init(talloc_tos());
    9462           4 :         if (ev == NULL) {
    9463           0 :                 printf("tevent_context_init failed\n");
    9464           0 :                 return false;
    9465             :         }
    9466             : 
    9467           4 :         state = talloc_zero(ev, struct posix_acl_oplock_state);
    9468           4 :         if (state == NULL) {
    9469           0 :                 printf("talloc failed\n");
    9470           0 :                 return false;
    9471             :         }
    9472           4 :         state->ev = ev;
    9473           4 :         state->cli = cli1;
    9474           4 :         state->got_break = &got_break;
    9475           4 :         state->acl_ret = &acl_ret;
    9476             : 
    9477           4 :         oplock_req = cli_smb_oplock_break_waiter_send(
    9478             :                 talloc_tos(), ev, cli1);
    9479           4 :         if (oplock_req == NULL) {
    9480           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    9481           0 :                 return false;
    9482             :         }
    9483           4 :         tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
    9484             : 
    9485             :         /* Get ACL on POSIX connection - should break oplock. */
    9486           4 :         getacl_req = cli_posix_getacl_send(talloc_tos(),
    9487             :                                 ev,
    9488             :                                 cli2,
    9489             :                                 fname);
    9490           4 :         if (getacl_req == NULL) {
    9491           0 :                 printf("cli_posix_getacl_send failed\n");
    9492           0 :                 return false;
    9493             :         }
    9494           4 :         tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
    9495             : 
    9496          36 :         while (!got_break || !acl_ret) {
    9497           0 :                 int ret;
    9498          32 :                 ret = tevent_loop_once(ev);
    9499          32 :                 if (ret == -1) {
    9500           0 :                         printf("tevent_loop_once failed: %s\n",
    9501           0 :                                strerror(errno));
    9502           0 :                         return false;
    9503             :                 }
    9504             :         }
    9505             : 
    9506           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9507           0 :                 printf("getacl failed (%s)\n", nt_errstr(state->status));
    9508           0 :                 correct = false;
    9509             :         }
    9510             : 
    9511           4 :         status = cli_close(cli1, fnum);
    9512           4 :         if (!NT_STATUS_IS_OK(status)) {
    9513           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    9514           0 :                 correct = false;
    9515             :         }
    9516             : 
    9517           4 :         status = cli_unlink(cli1,
    9518             :                         fname,
    9519             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9520           4 :         if (!NT_STATUS_IS_OK(status)) {
    9521           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    9522           0 :                 correct = false;
    9523             :         }
    9524             : 
    9525           4 :         if (!torture_close_connection(cli1)) {
    9526           0 :                 correct = false;
    9527             :         }
    9528           4 :         if (!torture_close_connection(cli2)) {
    9529           0 :                 correct = false;
    9530             :         }
    9531             : 
    9532           4 :         if (!got_break) {
    9533           0 :                 correct = false;
    9534             :         }
    9535             : 
    9536           4 :         printf("finished posix acl oplock test\n");
    9537             : 
    9538           4 :         return correct;
    9539             : }
    9540             : 
    9541           4 : static bool run_posix_acl_shareroot_test(int dummy)
    9542             : {
    9543           0 :         struct cli_state *cli;
    9544           0 :         NTSTATUS status;
    9545           4 :         bool correct = false;
    9546           4 :         char *posix_acl = NULL;
    9547           4 :         size_t posix_acl_len = 0;
    9548           4 :         uint16_t num_file_acls = 0;
    9549           4 :         uint16_t num_dir_acls = 0;
    9550           0 :         uint16_t i;
    9551           4 :         uint32_t expected_size = 0;
    9552           4 :         bool got_user = false;
    9553           4 :         bool got_group = false;
    9554           4 :         bool got_other = false;
    9555           4 :         TALLOC_CTX *frame = NULL;
    9556             : 
    9557           4 :         frame = talloc_stackframe();
    9558             : 
    9559           4 :         printf("starting posix_acl_shareroot test\n");
    9560             : 
    9561           4 :         if (!torture_open_connection(&cli, 0)) {
    9562           0 :                 TALLOC_FREE(frame);
    9563           0 :                 return false;
    9564             :         }
    9565             : 
    9566           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9567             : 
    9568           4 :         status = torture_setup_unix_extensions(cli);
    9569           4 :         if (!NT_STATUS_IS_OK(status)) {
    9570           0 :                 printf("Failed to setup unix extensions\n");
    9571           0 :                 goto out;
    9572             :         }
    9573             : 
    9574             :         /* Get the POSIX ACL on the root of the share. */
    9575           4 :         status = cli_posix_getacl(cli,
    9576             :                                 ".",
    9577             :                                 frame,
    9578             :                                 &posix_acl_len,
    9579             :                                 &posix_acl);
    9580             : 
    9581           4 :         if (!NT_STATUS_IS_OK(status)) {
    9582           0 :                 printf("cli_posix_getacl of '.' failed (%s)\n",
    9583             :                         nt_errstr(status));
    9584           0 :                 goto out;
    9585             :         }
    9586             : 
    9587           4 :         if (posix_acl_len < 6 ||
    9588           4 :                         SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
    9589           0 :                 printf("getfacl ., unknown POSIX acl version %u.\n",
    9590           0 :                         (unsigned int)CVAL(posix_acl,0) );
    9591           0 :                 goto out;
    9592             :         }
    9593             : 
    9594           4 :         num_file_acls = SVAL(posix_acl,2);
    9595           4 :         num_dir_acls = SVAL(posix_acl,4);
    9596           4 :         expected_size = SMB_POSIX_ACL_HEADER_SIZE +
    9597           4 :                                 SMB_POSIX_ACL_ENTRY_SIZE*
    9598           4 :                                 (num_file_acls+num_dir_acls);
    9599             : 
    9600           4 :         if (posix_acl_len != expected_size) {
    9601           0 :                 printf("incorrect POSIX acl buffer size "
    9602             :                         "(should be %u, was %u).\n",
    9603             :                         (unsigned int)expected_size,
    9604             :                         (unsigned int)posix_acl_len);
    9605           0 :                 goto out;
    9606             :         }
    9607             : 
    9608             :         /*
    9609             :          * We don't need to know what the ACL's are
    9610             :          * we just need to know we have at least 3
    9611             :          * file entries (u,g,o).
    9612             :          */
    9613             : 
    9614          16 :         for (i = 0; i < num_file_acls; i++) {
    9615          12 :                 unsigned char tagtype =
    9616          12 :                         CVAL(posix_acl,
    9617             :                                 SMB_POSIX_ACL_HEADER_SIZE+
    9618             :                                 (i*SMB_POSIX_ACL_ENTRY_SIZE));
    9619             : 
    9620          12 :                 switch(tagtype) {
    9621           4 :                         case SMB_POSIX_ACL_USER_OBJ:
    9622           4 :                                 got_user = true;
    9623           4 :                                 break;
    9624           4 :                         case SMB_POSIX_ACL_GROUP_OBJ:
    9625           4 :                                 got_group = true;
    9626           4 :                                 break;
    9627           4 :                         case SMB_POSIX_ACL_OTHER:
    9628           4 :                                 got_other = true;
    9629           4 :                                 break;
    9630           0 :                         default:
    9631           0 :                                 break;
    9632             :                 }
    9633             :         }
    9634             : 
    9635           4 :         if (!got_user) {
    9636           0 :                 printf("Missing user entry\n");
    9637           0 :                 goto out;
    9638             :         }
    9639             : 
    9640           4 :         if (!got_group) {
    9641           0 :                 printf("Missing group entry\n");
    9642           0 :                 goto out;
    9643             :         }
    9644             : 
    9645           4 :         if (!got_other) {
    9646           0 :                 printf("Missing other entry\n");
    9647           0 :                 goto out;
    9648             :         }
    9649             : 
    9650           4 :         correct = true;
    9651             : 
    9652           4 :   out:
    9653             : 
    9654           4 :         if (!torture_close_connection(cli)) {
    9655           0 :                 correct = false;
    9656             :         }
    9657             : 
    9658           4 :         printf("finished posix acl shareroot test\n");
    9659           4 :         TALLOC_FREE(frame);
    9660             : 
    9661           4 :         return correct;
    9662             : }
    9663             : 
    9664             : static uint32_t open_attrs_table[] = {
    9665             :                 FILE_ATTRIBUTE_NORMAL,
    9666             :                 FILE_ATTRIBUTE_ARCHIVE,
    9667             :                 FILE_ATTRIBUTE_READONLY,
    9668             :                 FILE_ATTRIBUTE_HIDDEN,
    9669             :                 FILE_ATTRIBUTE_SYSTEM,
    9670             : 
    9671             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
    9672             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
    9673             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
    9674             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9675             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9676             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9677             : 
    9678             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9679             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9680             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9681             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
    9682             : };
    9683             : 
    9684             : struct trunc_open_results {
    9685             :         unsigned int num;
    9686             :         uint32_t init_attr;
    9687             :         uint32_t trunc_attr;
    9688             :         uint32_t result_attr;
    9689             : };
    9690             : 
    9691             : static struct trunc_open_results attr_results[] = {
    9692             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9693             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9694             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9695             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9696             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9697             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9698             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9699             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9700             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9701             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9702             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9703             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9704             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9705             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9706             :         { 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 },
    9707             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9708             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9709             :         { 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 },
    9710             :         { 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 },
    9711             :         { 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 },
    9712             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9713             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9714             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9715             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9716             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9717             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
    9718             : };
    9719             : 
    9720           0 : static bool run_openattrtest(int dummy)
    9721             : {
    9722           0 :         static struct cli_state *cli1;
    9723           0 :         const char *fname = "\\openattr.file";
    9724           0 :         uint16_t fnum1;
    9725           0 :         bool correct = True;
    9726           0 :         uint32_t attr;
    9727           0 :         unsigned int i, j, k, l;
    9728           0 :         NTSTATUS status;
    9729             : 
    9730           0 :         printf("starting open attr test\n");
    9731             : 
    9732           0 :         if (!torture_open_connection(&cli1, 0)) {
    9733           0 :                 return False;
    9734             :         }
    9735             : 
    9736           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9737             : 
    9738           0 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
    9739           0 :                 cli_setatr(cli1, fname, 0, 0);
    9740           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9741             : 
    9742           0 :                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
    9743             :                                        open_attrs_table[i], FILE_SHARE_NONE,
    9744             :                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    9745           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9746           0 :                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9747           0 :                         return False;
    9748             :                 }
    9749             : 
    9750           0 :                 status = cli_close(cli1, fnum1);
    9751           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9752           0 :                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9753           0 :                         return False;
    9754             :                 }
    9755             : 
    9756           0 :                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
    9757           0 :                         status = cli_ntcreate(cli1, fname, 0,
    9758             :                                               FILE_READ_DATA|FILE_WRITE_DATA,
    9759             :                                               open_attrs_table[j],
    9760             :                                               FILE_SHARE_NONE, FILE_OVERWRITE,
    9761             :                                               0, 0, &fnum1, NULL);
    9762           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9763           0 :                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9764           0 :                                         if (attr_results[l].num == k) {
    9765           0 :                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
    9766             :                                                                 k, open_attrs_table[i],
    9767             :                                                                 open_attrs_table[j],
    9768             :                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
    9769           0 :                                                 correct = False;
    9770             :                                         }
    9771             :                                 }
    9772             : 
    9773           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    9774           0 :                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
    9775             :                                                         k, open_attrs_table[i], open_attrs_table[j],
    9776             :                                                         nt_errstr(status));
    9777           0 :                                         correct = False;
    9778             :                                 }
    9779             : #if 0
    9780             :                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
    9781             : #endif
    9782           0 :                                 k++;
    9783           0 :                                 continue;
    9784             :                         }
    9785             : 
    9786           0 :                         status = cli_close(cli1, fnum1);
    9787           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9788           0 :                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
    9789           0 :                                 return False;
    9790             :                         }
    9791             : 
    9792           0 :                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
    9793           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9794           0 :                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
    9795           0 :                                 return False;
    9796             :                         }
    9797             : 
    9798             : #if 0
    9799             :                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
    9800             :                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
    9801             : #endif
    9802             : 
    9803           0 :                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9804           0 :                                 if (attr_results[l].num == k) {
    9805           0 :                                         if (attr != attr_results[l].result_attr ||
    9806           0 :                                                         open_attrs_table[i] != attr_results[l].init_attr ||
    9807           0 :                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
    9808           0 :                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
    9809             :                                                 open_attrs_table[i],
    9810             :                                                 open_attrs_table[j],
    9811             :                                                 (unsigned int)attr,
    9812             :                                                 attr_results[l].result_attr);
    9813           0 :                                                 correct = False;
    9814             :                                         }
    9815           0 :                                         break;
    9816             :                                 }
    9817             :                         }
    9818           0 :                         k++;
    9819             :                 }
    9820             :         }
    9821             : 
    9822           0 :         cli_setatr(cli1, fname, 0, 0);
    9823           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9824             : 
    9825           0 :         printf("open attr test %s.\n", correct ? "passed" : "failed");
    9826             : 
    9827           0 :         if (!torture_close_connection(cli1)) {
    9828           0 :                 correct = False;
    9829             :         }
    9830           0 :         return correct;
    9831             : }
    9832             : 
    9833           0 : static NTSTATUS list_fn(struct file_info *finfo,
    9834             :                     const char *name, void *state)
    9835             : {
    9836           0 :         int *matched = (int *)state;
    9837           0 :         if (matched != NULL) {
    9838           0 :                 *matched += 1;
    9839             :         }
    9840           0 :         return NT_STATUS_OK;
    9841             : }
    9842             : 
    9843             : /*
    9844             :   test directory listing speed
    9845             :  */
    9846           5 : static bool run_dirtest(int dummy)
    9847             : {
    9848           0 :         int i;
    9849           0 :         static struct cli_state *cli;
    9850           0 :         uint16_t fnum;
    9851           0 :         struct timeval core_start;
    9852           5 :         bool correct = True;
    9853           0 :         int matched;
    9854             : 
    9855           5 :         printf("starting directory test\n");
    9856             : 
    9857           5 :         if (!torture_open_connection(&cli, 0)) {
    9858           0 :                 return False;
    9859             :         }
    9860             : 
    9861           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9862             : 
    9863           5 :         srandom(0);
    9864         505 :         for (i=0;i<torture_numops;i++) {
    9865           0 :                 fstring fname;
    9866         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9867         500 :                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
    9868           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
    9869           0 :                         return False;
    9870             :                 }
    9871         500 :                 cli_close(cli, fnum);
    9872             :         }
    9873             : 
    9874           5 :         core_start = timeval_current();
    9875             : 
    9876           5 :         matched = 0;
    9877           5 :         cli_list(cli, "a*.*", 0, list_fn, &matched);
    9878           5 :         printf("Matched %d\n", matched);
    9879             : 
    9880           5 :         matched = 0;
    9881           5 :         cli_list(cli, "b*.*", 0, list_fn, &matched);
    9882           5 :         printf("Matched %d\n", matched);
    9883             : 
    9884           5 :         matched = 0;
    9885           5 :         cli_list(cli, "xyzabc", 0, list_fn, &matched);
    9886           5 :         printf("Matched %d\n", matched);
    9887             : 
    9888           5 :         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
    9889             : 
    9890           5 :         srandom(0);
    9891         505 :         for (i=0;i<torture_numops;i++) {
    9892           0 :                 fstring fname;
    9893         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9894         500 :                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9895             :         }
    9896             : 
    9897           5 :         if (!torture_close_connection(cli)) {
    9898           0 :                 correct = False;
    9899             :         }
    9900             : 
    9901           5 :         printf("finished dirtest\n");
    9902             : 
    9903           5 :         return correct;
    9904             : }
    9905             : 
    9906           0 : static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
    9907             :                    void *state)
    9908             : {
    9909           0 :         struct cli_state *pcli = (struct cli_state *)state;
    9910           0 :         fstring fname;
    9911           0 :         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
    9912             : 
    9913           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
    9914           0 :                 return NT_STATUS_OK;
    9915             : 
    9916           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    9917           0 :                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
    9918           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
    9919             :         } else {
    9920           0 :                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
    9921           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
    9922             :         }
    9923           0 :         return NT_STATUS_OK;
    9924             : }
    9925             : 
    9926             : 
    9927             : /*
    9928             :    send a raw ioctl - used by the torture code
    9929             : */
    9930      327690 : static NTSTATUS cli_raw_ioctl(struct cli_state *cli,
    9931             :                               uint16_t fnum,
    9932             :                               uint32_t code,
    9933             :                               DATA_BLOB *blob)
    9934             : {
    9935           0 :         uint16_t vwv[3];
    9936           0 :         NTSTATUS status;
    9937             : 
    9938      327690 :         PUSH_LE_U16(vwv + 0, 0, fnum);
    9939      327690 :         PUSH_LE_U16(vwv + 1, 0, code >> 16);
    9940      327690 :         PUSH_LE_U16(vwv + 2, 0, (code & 0xFFFF));
    9941             : 
    9942      327690 :         status = cli_smb(talloc_tos(),
    9943             :                          cli,
    9944             :                          SMBioctl,
    9945             :                          0,
    9946             :                          3,
    9947             :                          vwv,
    9948             :                          0,
    9949             :                          NULL,
    9950             :                          NULL,
    9951             :                          0,
    9952             :                          NULL,
    9953             :                          NULL,
    9954             :                          NULL,
    9955             :                          NULL);
    9956      327690 :         if (!NT_STATUS_IS_OK(status)) {
    9957      327682 :                 return status;
    9958             :         }
    9959           8 :         *blob = data_blob_null;
    9960           8 :         return NT_STATUS_OK;
    9961             : }
    9962             : 
    9963             : /*
    9964             :   sees what IOCTLs are supported
    9965             :  */
    9966           5 : bool torture_ioctl_test(int dummy)
    9967             : {
    9968           0 :         static struct cli_state *cli;
    9969           0 :         uint16_t device, function;
    9970           0 :         uint16_t fnum;
    9971           5 :         const char *fname = "\\ioctl.dat";
    9972           0 :         DATA_BLOB blob;
    9973           0 :         NTSTATUS status;
    9974             : 
    9975           5 :         if (!torture_open_connection(&cli, 0)) {
    9976           0 :                 return False;
    9977             :         }
    9978             : 
    9979           5 :         printf("starting ioctl test\n");
    9980             : 
    9981           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9982             : 
    9983           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    9984           5 :         if (!NT_STATUS_IS_OK(status)) {
    9985           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9986           0 :                 return False;
    9987             :         }
    9988             : 
    9989           5 :         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
    9990           5 :         printf("ioctl device info: %s\n", nt_errstr(status));
    9991             : 
    9992           5 :         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
    9993           5 :         printf("ioctl job info: %s\n", nt_errstr(status));
    9994             : 
    9995        1285 :         for (device=0;device<0x100;device++) {
    9996        1280 :                 printf("ioctl test with device = 0x%x\n", device);
    9997      328960 :                 for (function=0;function<0x100;function++) {
    9998      327680 :                         uint32_t code = (device<<16) | function;
    9999             : 
   10000      327680 :                         status = cli_raw_ioctl(cli, fnum, code, &blob);
   10001             : 
   10002      327680 :                         if (NT_STATUS_IS_OK(status)) {
   10003           4 :                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
   10004           4 :                                        (int)blob.length);
   10005           4 :                                 data_blob_free(&blob);
   10006             :                         }
   10007             :                 }
   10008             :         }
   10009             : 
   10010           5 :         if (!torture_close_connection(cli)) {
   10011           0 :                 return False;
   10012             :         }
   10013             : 
   10014           5 :         return True;
   10015             : }
   10016             : 
   10017             : 
   10018             : /*
   10019             :   tries variants of chkpath
   10020             :  */
   10021           5 : bool torture_chkpath_test(int dummy)
   10022             : {
   10023           0 :         static struct cli_state *cli;
   10024           0 :         uint16_t fnum;
   10025           0 :         bool ret;
   10026           0 :         NTSTATUS status;
   10027             : 
   10028           5 :         if (!torture_open_connection(&cli, 0)) {
   10029           0 :                 return False;
   10030             :         }
   10031             : 
   10032           5 :         printf("starting chkpath test\n");
   10033             : 
   10034             :         /* cleanup from an old run */
   10035           5 :         torture_deltree(cli, "\\chkpath.dir");
   10036             : 
   10037           5 :         status = cli_mkdir(cli, "\\chkpath.dir");
   10038           5 :         if (!NT_STATUS_IS_OK(status)) {
   10039           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   10040           0 :                 return False;
   10041             :         }
   10042             : 
   10043           5 :         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
   10044           5 :         if (!NT_STATUS_IS_OK(status)) {
   10045           0 :                 printf("mkdir2 failed : %s\n", nt_errstr(status));
   10046           0 :                 return False;
   10047             :         }
   10048             : 
   10049           5 :         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
   10050             :                           DENY_NONE, &fnum);
   10051           5 :         if (!NT_STATUS_IS_OK(status)) {
   10052           0 :                 printf("open1 failed (%s)\n", nt_errstr(status));
   10053           0 :                 return False;
   10054             :         }
   10055           5 :         cli_close(cli, fnum);
   10056             : 
   10057           5 :         status = cli_chkpath(cli, "\\chkpath.dir");
   10058           5 :         if (!NT_STATUS_IS_OK(status)) {
   10059           0 :                 printf("chkpath1 failed: %s\n", nt_errstr(status));
   10060           0 :                 ret = False;
   10061             :         }
   10062             : 
   10063           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
   10064           5 :         if (!NT_STATUS_IS_OK(status)) {
   10065           0 :                 printf("chkpath2 failed: %s\n", nt_errstr(status));
   10066           0 :                 ret = False;
   10067             :         }
   10068             : 
   10069           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
   10070           5 :         if (!NT_STATUS_IS_OK(status)) {
   10071           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10072           5 :                                   NT_STATUS_NOT_A_DIRECTORY);
   10073             :         } else {
   10074           0 :                 printf("* chkpath on a file should fail\n");
   10075           0 :                 ret = False;
   10076             :         }
   10077             : 
   10078           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
   10079           5 :         if (!NT_STATUS_IS_OK(status)) {
   10080           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
   10081           5 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
   10082             :         } else {
   10083           0 :                 printf("* chkpath on a non existent file should fail\n");
   10084           0 :                 ret = False;
   10085             :         }
   10086             : 
   10087           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
   10088           5 :         if (!NT_STATUS_IS_OK(status)) {
   10089           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10090           5 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
   10091             :         } else {
   10092           0 :                 printf("* chkpath on a non existent component should fail\n");
   10093           0 :                 ret = False;
   10094             :         }
   10095             : 
   10096           5 :         torture_deltree(cli, "\\chkpath.dir");
   10097             : 
   10098           5 :         if (!torture_close_connection(cli)) {
   10099           0 :                 return False;
   10100             :         }
   10101             : 
   10102           5 :         return ret;
   10103             : }
   10104             : 
   10105           0 : static bool run_eatest(int dummy)
   10106             : {
   10107           0 :         static struct cli_state *cli;
   10108           0 :         const char *fname = "\\eatest.txt";
   10109           0 :         bool correct = True;
   10110           0 :         uint16_t fnum;
   10111           0 :         size_t i, num_eas;
   10112           0 :         struct ea_struct *ea_list = NULL;
   10113           0 :         TALLOC_CTX *mem_ctx = talloc_init("eatest");
   10114           0 :         NTSTATUS status;
   10115             : 
   10116           0 :         printf("starting eatest\n");
   10117             : 
   10118           0 :         if (!torture_open_connection(&cli, 0)) {
   10119           0 :                 talloc_destroy(mem_ctx);
   10120           0 :                 return False;
   10121             :         }
   10122             : 
   10123           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10124             : 
   10125           0 :         status = cli_ntcreate(cli, fname, 0,
   10126             :                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10127             :                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
   10128             :                               0x4044, 0, &fnum, NULL);
   10129           0 :         if (!NT_STATUS_IS_OK(status)) {
   10130           0 :                 printf("open failed - %s\n", nt_errstr(status));
   10131           0 :                 talloc_destroy(mem_ctx);
   10132           0 :                 return False;
   10133             :         }
   10134             : 
   10135           0 :         for (i = 0; i < 10; i++) {
   10136           0 :                 fstring ea_name, ea_val;
   10137             : 
   10138           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
   10139           0 :                 memset(ea_val, (char)i+1, i+1);
   10140           0 :                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
   10141           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10142           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10143             :                                nt_errstr(status));
   10144           0 :                         talloc_destroy(mem_ctx);
   10145           0 :                         return False;
   10146             :                 }
   10147             :         }
   10148             : 
   10149           0 :         cli_close(cli, fnum);
   10150           0 :         for (i = 0; i < 10; i++) {
   10151           0 :                 fstring ea_name, ea_val;
   10152             : 
   10153           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
   10154           0 :                 memset(ea_val, (char)i+1, i+1);
   10155           0 :                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
   10156           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10157           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10158             :                                nt_errstr(status));
   10159           0 :                         talloc_destroy(mem_ctx);
   10160           0 :                         return False;
   10161             :                 }
   10162             :         }
   10163             : 
   10164           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10165           0 :         if (!NT_STATUS_IS_OK(status)) {
   10166           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10167           0 :                 correct = False;
   10168             :         }
   10169             : 
   10170           0 :         printf("num_eas = %d\n", (int)num_eas);
   10171             : 
   10172           0 :         if (num_eas != 20) {
   10173           0 :                 printf("Should be 20 EA's stored... failing.\n");
   10174           0 :                 correct = False;
   10175             :         }
   10176             : 
   10177           0 :         for (i = 0; i < num_eas; i++) {
   10178           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10179           0 :                 dump_data(0, ea_list[i].value.data,
   10180           0 :                           ea_list[i].value.length);
   10181             :         }
   10182             : 
   10183             :         /* Setting EA's to zero length deletes them. Test this */
   10184           0 :         printf("Now deleting all EA's - case independent....\n");
   10185             : 
   10186             : #if 1
   10187           0 :         cli_set_ea_path(cli, fname, "", "", 0);
   10188             : #else
   10189             :         for (i = 0; i < 20; i++) {
   10190             :                 fstring ea_name;
   10191             :                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
   10192             :                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
   10193             :                 if (!NT_STATUS_IS_OK(status)) {
   10194             :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10195             :                                nt_errstr(status));
   10196             :                         talloc_destroy(mem_ctx);
   10197             :                         return False;
   10198             :                 }
   10199             :         }
   10200             : #endif
   10201             : 
   10202           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10203           0 :         if (!NT_STATUS_IS_OK(status)) {
   10204           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10205           0 :                 correct = False;
   10206             :         }
   10207             : 
   10208           0 :         printf("num_eas = %d\n", (int)num_eas);
   10209           0 :         for (i = 0; i < num_eas; i++) {
   10210           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10211           0 :                 dump_data(0, ea_list[i].value.data,
   10212           0 :                           ea_list[i].value.length);
   10213             :         }
   10214             : 
   10215           0 :         if (num_eas != 0) {
   10216           0 :                 printf("deleting EA's failed.\n");
   10217           0 :                 correct = False;
   10218             :         }
   10219             : 
   10220             :         /* Try and delete a non existent EA. */
   10221           0 :         status = cli_set_ea_path(cli, fname, "foo", "", 0);
   10222           0 :         if (!NT_STATUS_IS_OK(status)) {
   10223           0 :                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
   10224             :                        nt_errstr(status));
   10225           0 :                 correct = False;
   10226             :         }
   10227             : 
   10228           0 :         talloc_destroy(mem_ctx);
   10229           0 :         if (!torture_close_connection(cli)) {
   10230           0 :                 correct = False;
   10231             :         }
   10232             : 
   10233           0 :         return correct;
   10234             : }
   10235             : 
   10236           0 : static bool run_dirtest1(int dummy)
   10237             : {
   10238           0 :         int i;
   10239           0 :         static struct cli_state *cli;
   10240           0 :         uint16_t fnum;
   10241           0 :         int num_seen;
   10242           0 :         bool correct = True;
   10243             : 
   10244           0 :         printf("starting directory test\n");
   10245             : 
   10246           0 :         if (!torture_open_connection(&cli, 0)) {
   10247           0 :                 return False;
   10248             :         }
   10249             : 
   10250           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10251             : 
   10252           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10253           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10254           0 :         cli_rmdir(cli, "\\LISTDIR");
   10255           0 :         cli_mkdir(cli, "\\LISTDIR");
   10256             : 
   10257             :         /* Create 1000 files and 1000 directories. */
   10258           0 :         for (i=0;i<1000;i++) {
   10259           0 :                 fstring fname;
   10260           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
   10261           0 :                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10262             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
   10263             :                                    0, 0, &fnum, NULL))) {
   10264           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10265           0 :                         return False;
   10266             :                 }
   10267           0 :                 cli_close(cli, fnum);
   10268             :         }
   10269           0 :         for (i=0;i<1000;i++) {
   10270           0 :                 fstring fname;
   10271           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
   10272           0 :                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
   10273           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10274           0 :                         return False;
   10275             :                 }
   10276             :         }
   10277             : 
   10278             :         /* Now ensure that doing an old list sees both files and directories. */
   10279           0 :         num_seen = 0;
   10280           0 :         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10281           0 :         printf("num_seen = %d\n", num_seen );
   10282             :         /* We should see 100 files + 1000 directories + . and .. */
   10283           0 :         if (num_seen != 2002)
   10284           0 :                 correct = False;
   10285             : 
   10286             :         /* Ensure if we have the "must have" bits we only see the
   10287             :          * relevant entries.
   10288             :          */
   10289           0 :         num_seen = 0;
   10290           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10291           0 :         printf("num_seen = %d\n", num_seen );
   10292           0 :         if (num_seen != 1002)
   10293           0 :                 correct = False;
   10294             : 
   10295           0 :         num_seen = 0;
   10296           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10297           0 :         printf("num_seen = %d\n", num_seen );
   10298           0 :         if (num_seen != 1000)
   10299           0 :                 correct = False;
   10300             : 
   10301             :         /* Delete everything. */
   10302           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10303           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10304           0 :         cli_rmdir(cli, "\\LISTDIR");
   10305             : 
   10306             : #if 0
   10307             :         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
   10308             :         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
   10309             :         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
   10310             : #endif
   10311             : 
   10312           0 :         if (!torture_close_connection(cli)) {
   10313           0 :                 correct = False;
   10314             :         }
   10315             : 
   10316           0 :         printf("finished dirtest1\n");
   10317             : 
   10318           0 :         return correct;
   10319             : }
   10320             : 
   10321           0 : static bool run_error_map_extract(int dummy) {
   10322             : 
   10323           0 :         static struct cli_state *c_dos;
   10324           0 :         static struct cli_state *c_nt;
   10325           0 :         NTSTATUS status;
   10326             : 
   10327           0 :         uint32_t error;
   10328             : 
   10329           0 :         uint32_t errnum;
   10330           0 :         uint8_t errclass;
   10331             : 
   10332           0 :         NTSTATUS nt_status;
   10333             : 
   10334           0 :         fstring user;
   10335             : 
   10336             :         /* NT-Error connection */
   10337             : 
   10338           0 :         disable_spnego = true;
   10339           0 :         if (!(c_nt = open_nbt_connection())) {
   10340           0 :                 disable_spnego = false;
   10341           0 :                 return False;
   10342             :         }
   10343           0 :         disable_spnego = false;
   10344             : 
   10345           0 :         status = smbXcli_negprot(c_nt->conn,
   10346           0 :                                  c_nt->timeout,
   10347             :                                  PROTOCOL_CORE,
   10348             :                                  PROTOCOL_NT1,
   10349             :                                  NULL,
   10350             :                                  NULL,
   10351             :                                  NULL);
   10352             : 
   10353           0 :         if (!NT_STATUS_IS_OK(status)) {
   10354           0 :                 printf("%s rejected the NT-error negprot (%s)\n", host,
   10355             :                        nt_errstr(status));
   10356           0 :                 cli_shutdown(c_nt);
   10357           0 :                 return False;
   10358             :         }
   10359             : 
   10360           0 :         status = cli_session_setup_anon(c_nt);
   10361           0 :         if (!NT_STATUS_IS_OK(status)) {
   10362           0 :                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
   10363           0 :                 return False;
   10364             :         }
   10365             : 
   10366             :         /* DOS-Error connection */
   10367             : 
   10368           0 :         disable_spnego = true;
   10369           0 :         force_dos_errors = true;
   10370           0 :         if (!(c_dos = open_nbt_connection())) {
   10371           0 :                 disable_spnego = false;
   10372           0 :                 force_dos_errors = false;
   10373           0 :                 return False;
   10374             :         }
   10375           0 :         disable_spnego = false;
   10376           0 :         force_dos_errors = false;
   10377             : 
   10378           0 :         status = smbXcli_negprot(c_dos->conn,
   10379           0 :                                  c_dos->timeout,
   10380             :                                  PROTOCOL_CORE,
   10381             :                                  PROTOCOL_NT1,
   10382             :                                  NULL,
   10383             :                                  NULL,
   10384             :                                  NULL);
   10385           0 :         if (!NT_STATUS_IS_OK(status)) {
   10386           0 :                 printf("%s rejected the DOS-error negprot (%s)\n", host,
   10387             :                        nt_errstr(status));
   10388           0 :                 cli_shutdown(c_dos);
   10389           0 :                 return False;
   10390             :         }
   10391             : 
   10392           0 :         status = cli_session_setup_anon(c_dos);
   10393           0 :         if (!NT_STATUS_IS_OK(status)) {
   10394           0 :                 printf("%s rejected the DOS-error initial session setup (%s)\n",
   10395             :                         host, nt_errstr(status));
   10396           0 :                 return False;
   10397             :         }
   10398             : 
   10399           0 :         c_nt->map_dos_errors = false;
   10400           0 :         c_dos->map_dos_errors = false;
   10401             : 
   10402           0 :         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
   10403           0 :                 struct cli_credentials *user_creds = NULL;
   10404             : 
   10405           0 :                 fstr_sprintf(user, "%X", error);
   10406             : 
   10407           0 :                 user_creds = cli_session_creds_init(talloc_tos(),
   10408             :                                                     user,
   10409             :                                                     workgroup,
   10410             :                                                     NULL, /* realm */
   10411             :                                                     password,
   10412             :                                                     false, /* use_kerberos */
   10413             :                                                     false, /* fallback_after_kerberos */
   10414             :                                                     false, /* use_ccache */
   10415             :                                                     false); /* password_is_nt_hash */
   10416           0 :                 if (user_creds == NULL) {
   10417           0 :                         printf("cli_session_creds_init(%s) failed\n", user);
   10418           0 :                         return false;
   10419             :                 }
   10420             : 
   10421           0 :                 status = cli_session_setup_creds(c_nt, user_creds);
   10422           0 :                 if (NT_STATUS_IS_OK(status)) {
   10423           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10424             :                 }
   10425             : 
   10426             :                 /* Case #1: 32-bit NT errors */
   10427           0 :                 if (!NT_STATUS_IS_DOS(status)) {
   10428           0 :                         nt_status = status;
   10429             :                 } else {
   10430           0 :                         printf("/** Dos error on NT connection! (%s) */\n", 
   10431             :                                nt_errstr(status));
   10432           0 :                         nt_status = NT_STATUS(0xc0000000);
   10433             :                 }
   10434             : 
   10435           0 :                 status = cli_session_setup_creds(c_dos, user_creds);
   10436           0 :                 if (NT_STATUS_IS_OK(status)) {
   10437           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10438             :                 }
   10439             : 
   10440             :                 /* Case #1: 32-bit NT errors */
   10441           0 :                 if (NT_STATUS_IS_DOS(status)) {
   10442           0 :                         printf("/** NT error on DOS connection! (%s) */\n", 
   10443             :                                nt_errstr(status));
   10444           0 :                         errnum = errclass = 0;
   10445             :                 } else {
   10446           0 :                         errclass = NT_STATUS_DOS_CLASS(status);
   10447           0 :                         errnum = NT_STATUS_DOS_CODE(status);
   10448             :                 }
   10449             : 
   10450           0 :                 if (NT_STATUS_V(nt_status) != error) { 
   10451           0 :                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
   10452           0 :                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
   10453           0 :                                get_nt_error_c_code(talloc_tos(), nt_status));
   10454             :                 }
   10455             : 
   10456           0 :                 printf("\t{%s,\t%s,\t%s},\n", 
   10457             :                        smb_dos_err_class(errclass), 
   10458             :                        smb_dos_err_name(errclass, errnum), 
   10459           0 :                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
   10460             : 
   10461           0 :                 TALLOC_FREE(user_creds);
   10462             :         }
   10463           0 :         return True;
   10464             : }
   10465             : 
   10466           0 : static bool run_sesssetup_bench(int dummy)
   10467             : {
   10468           0 :         static struct cli_state *c;
   10469           0 :         const char *fname = "\\file.dat";
   10470           0 :         uint16_t fnum;
   10471           0 :         NTSTATUS status;
   10472           0 :         int i;
   10473             : 
   10474           0 :         if (!torture_open_connection(&c, 0)) {
   10475           0 :                 return false;
   10476             :         }
   10477             : 
   10478           0 :         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10479             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10480             :                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
   10481           0 :         if (!NT_STATUS_IS_OK(status)) {
   10482           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10483           0 :                 return false;
   10484             :         }
   10485             : 
   10486           0 :         for (i=0; i<torture_numops; i++) {
   10487           0 :                 status = cli_session_setup_creds(c, torture_creds);
   10488           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10489           0 :                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
   10490             :                                  __location__, nt_errstr(status));
   10491           0 :                         return false;
   10492             :                 }
   10493             : 
   10494           0 :                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
   10495             : 
   10496           0 :                 status = cli_ulogoff(c);
   10497           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10498           0 :                         d_printf("(%s) cli_ulogoff failed: %s\n",
   10499             :                                  __location__, nt_errstr(status));
   10500           0 :                         return false;
   10501             :                 }
   10502             :         }
   10503             : 
   10504           0 :         return true;
   10505             : }
   10506             : 
   10507           9 : static bool subst_test(const char *str, const char *user, const char *domain,
   10508             :                        uid_t uid, gid_t gid, const char *expected)
   10509             : {
   10510           9 :         char *subst;
   10511           9 :         bool result = true;
   10512             : 
   10513           9 :         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
   10514             : 
   10515           9 :         if (strcmp(subst, expected) != 0) {
   10516           0 :                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
   10517             :                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
   10518             :                        expected);
   10519           0 :                 result = false;
   10520             :         }
   10521             : 
   10522           9 :         TALLOC_FREE(subst);
   10523           9 :         return result;
   10524             : }
   10525             : 
   10526           5 : static void chain1_open_completion(struct tevent_req *req)
   10527             : {
   10528           0 :         uint16_t fnum;
   10529           0 :         NTSTATUS status;
   10530           5 :         status = cli_openx_recv(req, &fnum);
   10531           5 :         TALLOC_FREE(req);
   10532             : 
   10533           5 :         d_printf("cli_openx_recv returned %s: %d\n",
   10534             :                  nt_errstr(status),
   10535           5 :                  NT_STATUS_IS_OK(status) ? fnum : -1);
   10536           5 : }
   10537             : 
   10538           5 : static void chain1_write_completion(struct tevent_req *req)
   10539             : {
   10540           0 :         size_t written;
   10541           0 :         NTSTATUS status;
   10542           5 :         status = cli_write_andx_recv(req, &written);
   10543           5 :         TALLOC_FREE(req);
   10544             : 
   10545           5 :         d_printf("cli_write_andx_recv returned %s: %d\n",
   10546             :                  nt_errstr(status),
   10547           5 :                  NT_STATUS_IS_OK(status) ? (int)written : -1);
   10548           5 : }
   10549             : 
   10550           5 : static void chain1_close_completion(struct tevent_req *req)
   10551             : {
   10552           0 :         NTSTATUS status;
   10553           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10554             : 
   10555           5 :         status = cli_close_recv(req);
   10556           5 :         *done = true;
   10557             : 
   10558           5 :         TALLOC_FREE(req);
   10559             : 
   10560           5 :         d_printf("cli_close returned %s\n", nt_errstr(status));
   10561           5 : }
   10562             : 
   10563           5 : static bool run_chain1(int dummy)
   10564             : {
   10565           0 :         struct cli_state *cli1;
   10566           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10567           0 :         struct tevent_req *reqs[3], *smbreqs[3];
   10568           5 :         bool done = false;
   10569           5 :         const char *str = "foobar";
   10570           5 :         const char *fname = "\\test_chain";
   10571           0 :         NTSTATUS status;
   10572             : 
   10573           5 :         printf("starting chain1 test\n");
   10574           5 :         if (!torture_open_connection(&cli1, 0)) {
   10575           0 :                 return False;
   10576             :         }
   10577             : 
   10578           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10579             : 
   10580           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10581             : 
   10582           5 :         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
   10583             :                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
   10584           5 :         if (reqs[0] == NULL) return false;
   10585           5 :         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
   10586             : 
   10587             : 
   10588           5 :         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
   10589           5 :                                         (const uint8_t *)str, 0, strlen(str)+1,
   10590             :                                         smbreqs, 1, &smbreqs[1]);
   10591           5 :         if (reqs[1] == NULL) return false;
   10592           5 :         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
   10593             : 
   10594           5 :         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
   10595           5 :         if (reqs[2] == NULL) return false;
   10596           5 :         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
   10597             : 
   10598           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10599           5 :         if (!NT_STATUS_IS_OK(status)) {
   10600           0 :                 return false;
   10601             :         }
   10602             : 
   10603          35 :         while (!done) {
   10604          30 :                 tevent_loop_once(evt);
   10605             :         }
   10606             : 
   10607           5 :         torture_close_connection(cli1);
   10608           5 :         return True;
   10609             : }
   10610             : 
   10611           5 : static void chain2_sesssetup_completion(struct tevent_req *req)
   10612             : {
   10613           0 :         NTSTATUS status;
   10614           5 :         status = cli_session_setup_guest_recv(req);
   10615           5 :         d_printf("sesssetup returned %s\n", nt_errstr(status));
   10616           5 : }
   10617             : 
   10618           5 : static void chain2_tcon_completion(struct tevent_req *req)
   10619             : {
   10620           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10621           0 :         NTSTATUS status;
   10622           5 :         status = cli_tcon_andx_recv(req);
   10623           5 :         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
   10624           5 :         *done = true;
   10625           5 : }
   10626             : 
   10627           5 : static bool run_chain2(int dummy)
   10628             : {
   10629           0 :         struct cli_state *cli1;
   10630           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10631           0 :         struct tevent_req *reqs[2], *smbreqs[2];
   10632           5 :         bool done = false;
   10633           0 :         NTSTATUS status;
   10634           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
   10635             : 
   10636           5 :         printf("starting chain2 test\n");
   10637           5 :         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
   10638             :                                       port_to_use, SMB_SIGNING_DEFAULT, flags);
   10639           5 :         if (!NT_STATUS_IS_OK(status)) {
   10640           0 :                 return False;
   10641             :         }
   10642             : 
   10643           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10644             : 
   10645           5 :         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
   10646             :                                                  &smbreqs[0]);
   10647           5 :         if (reqs[0] == NULL) return false;
   10648           5 :         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
   10649             : 
   10650           5 :         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
   10651             :                                        "?????", NULL, 0, &smbreqs[1]);
   10652           5 :         if (reqs[1] == NULL) return false;
   10653           5 :         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
   10654             : 
   10655           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10656           5 :         if (!NT_STATUS_IS_OK(status)) {
   10657           0 :                 return false;
   10658             :         }
   10659             : 
   10660          30 :         while (!done) {
   10661          25 :                 tevent_loop_once(evt);
   10662             :         }
   10663             : 
   10664           5 :         torture_close_connection(cli1);
   10665           5 :         return True;
   10666             : }
   10667             : 
   10668             : 
   10669             : struct torture_createdel_state {
   10670             :         struct tevent_context *ev;
   10671             :         struct cli_state *cli;
   10672             : };
   10673             : 
   10674             : static void torture_createdel_created(struct tevent_req *subreq);
   10675             : static void torture_createdel_closed(struct tevent_req *subreq);
   10676             : 
   10677           0 : static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
   10678             :                                                  struct tevent_context *ev,
   10679             :                                                  struct cli_state *cli,
   10680             :                                                  const char *name)
   10681             : {
   10682           0 :         struct tevent_req *req, *subreq;
   10683           0 :         struct torture_createdel_state *state;
   10684             : 
   10685           0 :         req = tevent_req_create(mem_ctx, &state,
   10686             :                                 struct torture_createdel_state);
   10687           0 :         if (req == NULL) {
   10688           0 :                 return NULL;
   10689             :         }
   10690           0 :         state->ev = ev;
   10691           0 :         state->cli = cli;
   10692             : 
   10693           0 :         subreq = cli_ntcreate_send(
   10694             :                 state, ev, cli, name, 0,
   10695             :                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
   10696             :                 FILE_ATTRIBUTE_NORMAL,
   10697             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   10698             :                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
   10699             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
   10700             : 
   10701           0 :         if (tevent_req_nomem(subreq, req)) {
   10702           0 :                 return tevent_req_post(req, ev);
   10703             :         }
   10704           0 :         tevent_req_set_callback(subreq, torture_createdel_created, req);
   10705           0 :         return req;
   10706             : }
   10707             : 
   10708           0 : static void torture_createdel_created(struct tevent_req *subreq)
   10709             : {
   10710           0 :         struct tevent_req *req = tevent_req_callback_data(
   10711             :                 subreq, struct tevent_req);
   10712           0 :         struct torture_createdel_state *state = tevent_req_data(
   10713             :                 req, struct torture_createdel_state);
   10714           0 :         NTSTATUS status;
   10715           0 :         uint16_t fnum;
   10716             : 
   10717           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
   10718           0 :         TALLOC_FREE(subreq);
   10719           0 :         if (tevent_req_nterror(req, status)) {
   10720           0 :                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
   10721             :                            nt_errstr(status)));
   10722           0 :                 return;
   10723             :         }
   10724             : 
   10725           0 :         subreq = cli_close_send(state, state->ev, state->cli, fnum, 0);
   10726           0 :         if (tevent_req_nomem(subreq, req)) {
   10727           0 :                 return;
   10728             :         }
   10729           0 :         tevent_req_set_callback(subreq, torture_createdel_closed, req);
   10730             : }
   10731             : 
   10732           0 : static void torture_createdel_closed(struct tevent_req *subreq)
   10733             : {
   10734           0 :         struct tevent_req *req = tevent_req_callback_data(
   10735             :                 subreq, struct tevent_req);
   10736           0 :         NTSTATUS status;
   10737             : 
   10738           0 :         status = cli_close_recv(subreq);
   10739           0 :         if (tevent_req_nterror(req, status)) {
   10740           0 :                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
   10741           0 :                 return;
   10742             :         }
   10743           0 :         tevent_req_done(req);
   10744             : }
   10745             : 
   10746           0 : static NTSTATUS torture_createdel_recv(struct tevent_req *req)
   10747             : {
   10748           0 :         return tevent_req_simple_recv_ntstatus(req);
   10749             : }
   10750             : 
   10751             : struct torture_createdels_state {
   10752             :         struct tevent_context *ev;
   10753             :         struct cli_state *cli;
   10754             :         const char *base_name;
   10755             :         int sent;
   10756             :         int received;
   10757             :         int num_files;
   10758             :         struct tevent_req **reqs;
   10759             : };
   10760             : 
   10761             : static void torture_createdels_done(struct tevent_req *subreq);
   10762             : 
   10763           0 : static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
   10764             :                                                   struct tevent_context *ev,
   10765             :                                                   struct cli_state *cli,
   10766             :                                                   const char *base_name,
   10767             :                                                   int num_parallel,
   10768             :                                                   int num_files)
   10769             : {
   10770           0 :         struct tevent_req *req;
   10771           0 :         struct torture_createdels_state *state;
   10772           0 :         int i;
   10773             : 
   10774           0 :         req = tevent_req_create(mem_ctx, &state,
   10775             :                                 struct torture_createdels_state);
   10776           0 :         if (req == NULL) {
   10777           0 :                 return NULL;
   10778             :         }
   10779           0 :         state->ev = ev;
   10780           0 :         state->cli = cli;
   10781           0 :         state->base_name = talloc_strdup(state, base_name);
   10782           0 :         if (tevent_req_nomem(state->base_name, req)) {
   10783           0 :                 return tevent_req_post(req, ev);
   10784             :         }
   10785           0 :         state->num_files = MAX(num_parallel, num_files);
   10786           0 :         state->sent = 0;
   10787           0 :         state->received = 0;
   10788             : 
   10789           0 :         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
   10790           0 :         if (tevent_req_nomem(state->reqs, req)) {
   10791           0 :                 return tevent_req_post(req, ev);
   10792             :         }
   10793             : 
   10794           0 :         for (i=0; i<num_parallel; i++) {
   10795           0 :                 char *name;
   10796             : 
   10797           0 :                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10798           0 :                                        state->sent);
   10799           0 :                 if (tevent_req_nomem(name, req)) {
   10800           0 :                         return tevent_req_post(req, ev);
   10801             :                 }
   10802           0 :                 state->reqs[i] = torture_createdel_send(
   10803           0 :                         state->reqs, state->ev, state->cli, name);
   10804           0 :                 if (tevent_req_nomem(state->reqs[i], req)) {
   10805           0 :                         return tevent_req_post(req, ev);
   10806             :                 }
   10807           0 :                 name = talloc_move(state->reqs[i], &name);
   10808           0 :                 tevent_req_set_callback(state->reqs[i],
   10809             :                                         torture_createdels_done, req);
   10810           0 :                 state->sent += 1;
   10811             :         }
   10812           0 :         return req;
   10813             : }
   10814             : 
   10815           0 : static void torture_createdels_done(struct tevent_req *subreq)
   10816             : {
   10817           0 :         struct tevent_req *req = tevent_req_callback_data(
   10818             :                 subreq, struct tevent_req);
   10819           0 :         struct torture_createdels_state *state = tevent_req_data(
   10820             :                 req, struct torture_createdels_state);
   10821           0 :         size_t i, num_parallel = talloc_array_length(state->reqs);
   10822           0 :         NTSTATUS status;
   10823           0 :         char *name;
   10824             : 
   10825           0 :         status = torture_createdel_recv(subreq);
   10826           0 :         if (!NT_STATUS_IS_OK(status)){
   10827           0 :                 DEBUG(10, ("torture_createdel_recv returned %s\n",
   10828             :                            nt_errstr(status)));
   10829           0 :                 TALLOC_FREE(subreq);
   10830           0 :                 tevent_req_nterror(req, status);
   10831           0 :                 return;
   10832             :         }
   10833             : 
   10834           0 :         for (i=0; i<num_parallel; i++) {
   10835           0 :                 if (subreq == state->reqs[i]) {
   10836           0 :                         break;
   10837             :                 }
   10838             :         }
   10839           0 :         if (i == num_parallel) {
   10840           0 :                 DEBUG(10, ("received something we did not send\n"));
   10841           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
   10842           0 :                 return;
   10843             :         }
   10844           0 :         TALLOC_FREE(state->reqs[i]);
   10845             : 
   10846           0 :         if (state->sent >= state->num_files) {
   10847           0 :                 tevent_req_done(req);
   10848           0 :                 return;
   10849             :         }
   10850             : 
   10851           0 :         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10852             :                                state->sent);
   10853           0 :         if (tevent_req_nomem(name, req)) {
   10854           0 :                 return;
   10855             :         }
   10856           0 :         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
   10857             :                                                 state->cli, name);
   10858           0 :         if (tevent_req_nomem(state->reqs[i], req)) {
   10859           0 :                 return;
   10860             :         }
   10861           0 :         name = talloc_move(state->reqs[i], &name);
   10862           0 :         tevent_req_set_callback(state->reqs[i],      torture_createdels_done, req);
   10863           0 :         state->sent += 1;
   10864             : }
   10865             : 
   10866           0 : static NTSTATUS torture_createdels_recv(struct tevent_req *req)
   10867             : {
   10868           0 :         return tevent_req_simple_recv_ntstatus(req);
   10869             : }
   10870             : 
   10871             : struct swallow_notify_state {
   10872             :         struct tevent_context *ev;
   10873             :         struct cli_state *cli;
   10874             :         uint16_t fnum;
   10875             :         uint32_t completion_filter;
   10876             :         bool recursive;
   10877             :         bool (*fn)(uint32_t action, const char *name, void *priv);
   10878             :         void *priv;
   10879             : };
   10880             : 
   10881             : static void swallow_notify_done(struct tevent_req *subreq);
   10882             : 
   10883           0 : static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
   10884             :                                               struct tevent_context *ev,
   10885             :                                               struct cli_state *cli,
   10886             :                                               uint16_t fnum,
   10887             :                                               uint32_t completion_filter,
   10888             :                                               bool recursive,
   10889             :                                               bool (*fn)(uint32_t action,
   10890             :                                                          const char *name,
   10891             :                                                          void *priv),
   10892             :                                               void *priv)
   10893             : {
   10894           0 :         struct tevent_req *req, *subreq;
   10895           0 :         struct swallow_notify_state *state;
   10896             : 
   10897           0 :         req = tevent_req_create(mem_ctx, &state,
   10898             :                                 struct swallow_notify_state);
   10899           0 :         if (req == NULL) {
   10900           0 :                 return NULL;
   10901             :         }
   10902           0 :         state->ev = ev;
   10903           0 :         state->cli = cli;
   10904           0 :         state->fnum = fnum;
   10905           0 :         state->completion_filter = completion_filter;
   10906           0 :         state->recursive = recursive;
   10907           0 :         state->fn = fn;
   10908           0 :         state->priv = priv;
   10909             : 
   10910           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10911           0 :                                  0xffff, state->completion_filter,
   10912           0 :                                  state->recursive);
   10913           0 :         if (tevent_req_nomem(subreq, req)) {
   10914           0 :                 return tevent_req_post(req, ev);
   10915             :         }
   10916           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10917           0 :         return req;
   10918             : }
   10919             : 
   10920           0 : static void swallow_notify_done(struct tevent_req *subreq)
   10921             : {
   10922           0 :         struct tevent_req *req = tevent_req_callback_data(
   10923             :                 subreq, struct tevent_req);
   10924           0 :         struct swallow_notify_state *state = tevent_req_data(
   10925             :                 req, struct swallow_notify_state);
   10926           0 :         NTSTATUS status;
   10927           0 :         uint32_t i, num_changes;
   10928           0 :         struct notify_change *changes;
   10929             : 
   10930           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
   10931           0 :         TALLOC_FREE(subreq);
   10932           0 :         if (!NT_STATUS_IS_OK(status)) {
   10933           0 :                 DEBUG(10, ("cli_notify_recv returned %s\n",
   10934             :                            nt_errstr(status)));
   10935           0 :                 tevent_req_nterror(req, status);
   10936           0 :                 return;
   10937             :         }
   10938             : 
   10939           0 :         for (i=0; i<num_changes; i++) {
   10940           0 :                 state->fn(changes[i].action, changes[i].name, state->priv);
   10941             :         }
   10942           0 :         TALLOC_FREE(changes);
   10943             : 
   10944           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10945             :                                  0xffff, state->completion_filter,
   10946           0 :                                  state->recursive);
   10947           0 :         if (tevent_req_nomem(subreq, req)) {
   10948           0 :                 return;
   10949             :         }
   10950           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10951             : }
   10952             : 
   10953           0 : static bool print_notifies(uint32_t action, const char *name, void *priv)
   10954             : {
   10955           0 :         if (DEBUGLEVEL > 5) {
   10956           0 :                 d_printf("%d %s\n", (int)action, name);
   10957             :         }
   10958           0 :         return true;
   10959             : }
   10960             : 
   10961           0 : static void notify_bench_done(struct tevent_req *req)
   10962             : {
   10963           0 :         int *num_finished = (int *)tevent_req_callback_data_void(req);
   10964           0 :         *num_finished += 1;
   10965           0 : }
   10966             : 
   10967           0 : static bool run_notify_bench(int dummy)
   10968             : {
   10969           0 :         const char *dname = "\\notify-bench";
   10970           0 :         struct tevent_context *ev;
   10971           0 :         NTSTATUS status;
   10972           0 :         uint16_t dnum;
   10973           0 :         struct tevent_req *req1;
   10974           0 :         struct tevent_req *req2 = NULL;
   10975           0 :         int i, num_unc_names;
   10976           0 :         int num_finished = 0;
   10977             : 
   10978           0 :         printf("starting notify-bench test\n");
   10979             : 
   10980           0 :         if (use_multishare_conn) {
   10981           0 :                 char **unc_list;
   10982           0 :                 unc_list = file_lines_load(multishare_conn_fname,
   10983             :                                            &num_unc_names, 0, NULL);
   10984           0 :                 if (!unc_list || num_unc_names <= 0) {
   10985           0 :                         d_printf("Failed to load unc names list from '%s'\n",
   10986             :                                  multishare_conn_fname);
   10987           0 :                         return false;
   10988             :                 }
   10989           0 :                 TALLOC_FREE(unc_list);
   10990             :         } else {
   10991           0 :                 num_unc_names = 1;
   10992             :         }
   10993             : 
   10994           0 :         ev = samba_tevent_context_init(talloc_tos());
   10995           0 :         if (ev == NULL) {
   10996           0 :                 d_printf("tevent_context_init failed\n");
   10997           0 :                 return false;
   10998             :         }
   10999             : 
   11000           0 :         for (i=0; i<num_unc_names; i++) {
   11001           0 :                 struct cli_state *cli;
   11002           0 :                 char *base_fname;
   11003             : 
   11004           0 :                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
   11005             :                                              dname, i);
   11006           0 :                 if (base_fname == NULL) {
   11007           0 :                         return false;
   11008             :                 }
   11009             : 
   11010           0 :                 if (!torture_open_connection(&cli, i)) {
   11011           0 :                         return false;
   11012             :                 }
   11013             : 
   11014           0 :                 status = cli_ntcreate(cli, dname, 0,
   11015             :                                       MAXIMUM_ALLOWED_ACCESS,
   11016             :                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
   11017             :                                       FILE_SHARE_DELETE,
   11018             :                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
   11019             :                                       &dnum, NULL);
   11020             : 
   11021           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11022           0 :                         d_printf("Could not create %s: %s\n", dname,
   11023             :                                  nt_errstr(status));
   11024           0 :                         return false;
   11025             :                 }
   11026             : 
   11027           0 :                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
   11028             :                                            FILE_NOTIFY_CHANGE_FILE_NAME |
   11029             :                                            FILE_NOTIFY_CHANGE_DIR_NAME |
   11030             :                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
   11031             :                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
   11032             :                                            false, print_notifies, NULL);
   11033           0 :                 if (req1 == NULL) {
   11034           0 :                         d_printf("Could not create notify request\n");
   11035           0 :                         return false;
   11036             :                 }
   11037             : 
   11038           0 :                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
   11039             :                                                base_fname, 10, torture_numops);
   11040           0 :                 if (req2 == NULL) {
   11041           0 :                         d_printf("Could not create createdels request\n");
   11042           0 :                         return false;
   11043             :                 }
   11044           0 :                 TALLOC_FREE(base_fname);
   11045             : 
   11046           0 :                 tevent_req_set_callback(req2, notify_bench_done,
   11047             :                                         &num_finished);
   11048             :         }
   11049             : 
   11050           0 :         while (num_finished < num_unc_names) {
   11051           0 :                 int ret;
   11052           0 :                 ret = tevent_loop_once(ev);
   11053           0 :                 if (ret != 0) {
   11054           0 :                         d_printf("tevent_loop_once failed\n");
   11055           0 :                         return false;
   11056             :                 }
   11057             :         }
   11058             : 
   11059           0 :         if (!tevent_req_poll(req2, ev)) {
   11060           0 :                 d_printf("tevent_req_poll failed\n");
   11061             :         }
   11062             : 
   11063           0 :         status = torture_createdels_recv(req2);
   11064           0 :         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
   11065             : 
   11066           0 :         return true;
   11067             : }
   11068             : 
   11069           0 : static bool run_mangle1(int dummy)
   11070             : {
   11071           0 :         struct cli_state *cli;
   11072           0 :         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
   11073           0 :         uint16_t fnum;
   11074           0 :         fstring alt_name;
   11075           0 :         NTSTATUS status;
   11076             : 
   11077           0 :         printf("starting mangle1 test\n");
   11078           0 :         if (!torture_open_connection(&cli, 0)) {
   11079           0 :                 return False;
   11080             :         }
   11081             : 
   11082           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11083             : 
   11084           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11085             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11086             :                               0, 0, &fnum, NULL);
   11087           0 :         if (!NT_STATUS_IS_OK(status)) {
   11088           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11089           0 :                 return false;
   11090             :         }
   11091           0 :         cli_close(cli, fnum);
   11092             : 
   11093           0 :         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
   11094           0 :         if (!NT_STATUS_IS_OK(status)) {
   11095           0 :                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
   11096             :                          nt_errstr(status));
   11097           0 :                 return false;
   11098             :         }
   11099           0 :         d_printf("alt_name: %s\n", alt_name);
   11100             : 
   11101           0 :         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
   11102           0 :         if (!NT_STATUS_IS_OK(status)) {
   11103           0 :                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
   11104             :                          nt_errstr(status));
   11105           0 :                 return false;
   11106             :         }
   11107           0 :         cli_close(cli, fnum);
   11108             : 
   11109           0 :         status = cli_qpathinfo1(cli, alt_name, NULL, NULL, NULL, NULL, NULL);
   11110           0 :         if (!NT_STATUS_IS_OK(status)) {
   11111           0 :                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
   11112             :                          nt_errstr(status));
   11113           0 :                 return false;
   11114             :         }
   11115             : 
   11116           0 :         return true;
   11117             : }
   11118             : 
   11119           2 : static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
   11120             :                                                  const char *mask,
   11121             :                                                  void *state)
   11122             : {
   11123           2 :         if (f->short_name == NULL) {
   11124           2 :                 return NT_STATUS_OK;
   11125             :         }
   11126             : 
   11127           0 :         if (strlen(f->short_name) == 0) {
   11128           0 :                 return NT_STATUS_OK;
   11129             :         }
   11130             : 
   11131           0 :         printf("unexpected shortname: %s\n", f->short_name);
   11132             : 
   11133           0 :         return NT_STATUS_OBJECT_NAME_INVALID;
   11134             : }
   11135             : 
   11136           2 : static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
   11137             :                                             const char *mask,
   11138             :                                             void *state)
   11139             : {
   11140           2 :         char *name = state;
   11141             : 
   11142           2 :         printf("name: %s\n", f->name);
   11143           2 :         fstrcpy(name, f->name);
   11144           2 :         return NT_STATUS_OK;
   11145             : }
   11146             : 
   11147           2 : static bool run_mangle_illegal(int dummy)
   11148             : {
   11149           2 :         struct cli_state *cli = NULL;
   11150           2 :         struct cli_state *cli_posix = NULL;
   11151           2 :         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
   11152           2 :         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
   11153           2 :         char *mangled_path = NULL;
   11154           0 :         uint16_t fnum;
   11155           0 :         fstring name;
   11156           0 :         fstring alt_name;
   11157           0 :         NTSTATUS status;
   11158             : 
   11159           2 :         printf("starting mangle-illegal test\n");
   11160             : 
   11161           2 :         if (!torture_open_connection(&cli, 0)) {
   11162           0 :                 return False;
   11163             :         }
   11164             : 
   11165           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11166             : 
   11167           2 :         if (!torture_open_connection(&cli_posix, 0)) {
   11168           0 :                 return false;
   11169             :         }
   11170             : 
   11171           2 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   11172             : 
   11173           2 :         status = torture_setup_unix_extensions(cli_posix);
   11174           2 :         if (!NT_STATUS_IS_OK(status)) {
   11175           0 :                 return false;
   11176             :         }
   11177             : 
   11178           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11179           2 :         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
   11180           2 :         if (!NT_STATUS_IS_OK(status)) {
   11181           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   11182           0 :                 return False;
   11183             :         }
   11184             : 
   11185             :         /*
   11186             :          * Create a file with illegal NTFS characters and test that we
   11187             :          * get a usable mangled name
   11188             :          */
   11189             : 
   11190           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11191           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11192             : 
   11193           2 :         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
   11194             :                                 0600, &fnum);
   11195           2 :         if (!NT_STATUS_IS_OK(status)) {
   11196           0 :                 printf("POSIX create of %s failed (%s)\n",
   11197             :                        illegal_fname, nt_errstr(status));
   11198           0 :                 return false;
   11199             :         }
   11200             : 
   11201           2 :         status = cli_close(cli_posix, fnum);
   11202           2 :         if (!NT_STATUS_IS_OK(status)) {
   11203           0 :                 printf("close failed (%s)\n", nt_errstr(status));
   11204           0 :                 return false;
   11205             :         }
   11206             : 
   11207           2 :         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
   11208           2 :         if (!NT_STATUS_IS_OK(status)) {
   11209           0 :                 d_printf("cli_list failed: %s\n", nt_errstr(status));
   11210           0 :                 return false;
   11211             :         }
   11212             : 
   11213           2 :         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
   11214           2 :         if (mangled_path == NULL) {
   11215           0 :                 return false;
   11216             :         }
   11217             : 
   11218           2 :         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
   11219           2 :         if (!NT_STATUS_IS_OK(status)) {
   11220           0 :                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
   11221           0 :                 TALLOC_FREE(mangled_path);
   11222           0 :                 return false;
   11223             :         }
   11224           2 :         TALLOC_FREE(mangled_path);
   11225           2 :         cli_close(cli, fnum);
   11226             : 
   11227           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11228           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11229             : 
   11230             :         /*
   11231             :          * Create a file with a long name and check that we got *no* short name.
   11232             :          */
   11233             : 
   11234           2 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11235             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11236             :                               0, 0, &fnum, NULL);
   11237           2 :         if (!NT_STATUS_IS_OK(status)) {
   11238           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11239           0 :                 return false;
   11240             :         }
   11241           2 :         cli_close(cli, fnum);
   11242             : 
   11243           2 :         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
   11244           2 :         if (!NT_STATUS_IS_OK(status)) {
   11245           0 :                 d_printf("cli_list failed\n");
   11246           0 :                 return false;
   11247             :         }
   11248             : 
   11249           2 :         cli_unlink(cli, fname, 0);
   11250           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11251             : 
   11252           2 :         if (!torture_close_connection(cli_posix)) {
   11253           0 :                 return false;
   11254             :         }
   11255             : 
   11256           2 :         if (!torture_close_connection(cli)) {
   11257           0 :                 return false;
   11258             :         }
   11259             : 
   11260           2 :         return true;
   11261             : }
   11262             : 
   11263           0 : static size_t null_source(uint8_t *buf, size_t n, void *priv)
   11264             : {
   11265           0 :         size_t *to_pull = (size_t *)priv;
   11266           0 :         size_t thistime = *to_pull;
   11267             : 
   11268           0 :         thistime = MIN(thistime, n);
   11269           0 :         if (thistime == 0) {
   11270           0 :                 return 0;
   11271             :         }
   11272             : 
   11273           0 :         memset(buf, 0, thistime);
   11274           0 :         *to_pull -= thistime;
   11275           0 :         return thistime;
   11276             : }
   11277             : 
   11278           0 : static bool run_windows_write(int dummy)
   11279             : {
   11280           0 :         struct cli_state *cli1;
   11281           0 :         uint16_t fnum;
   11282           0 :         int i;
   11283           0 :         bool ret = false;
   11284           0 :         const char *fname = "\\writetest.txt";
   11285           0 :         struct timeval start_time;
   11286           0 :         double seconds;
   11287           0 :         double kbytes;
   11288           0 :         NTSTATUS status;
   11289             : 
   11290           0 :         printf("starting windows_write test\n");
   11291           0 :         if (!torture_open_connection(&cli1, 0)) {
   11292           0 :                 return False;
   11293             :         }
   11294             : 
   11295           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   11296           0 :         if (!NT_STATUS_IS_OK(status)) {
   11297           0 :                 printf("open failed (%s)\n", nt_errstr(status));
   11298           0 :                 return False;
   11299             :         }
   11300             : 
   11301           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   11302             : 
   11303           0 :         start_time = timeval_current();
   11304             : 
   11305           0 :         for (i=0; i<torture_numops; i++) {
   11306           0 :                 uint8_t c = 0;
   11307           0 :                 off_t start = i * torture_blocksize;
   11308           0 :                 size_t to_pull = torture_blocksize - 1;
   11309             : 
   11310           0 :                 status = cli_writeall(cli1, fnum, 0, &c,
   11311           0 :                                       start + torture_blocksize - 1, 1, NULL);
   11312           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11313           0 :                         printf("cli_write failed: %s\n", nt_errstr(status));
   11314           0 :                         goto fail;
   11315             :                 }
   11316             : 
   11317           0 :                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
   11318             :                                   null_source, &to_pull);
   11319           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11320           0 :                         printf("cli_push returned: %s\n", nt_errstr(status));
   11321           0 :                         goto fail;
   11322             :                 }
   11323             :         }
   11324             : 
   11325           0 :         seconds = timeval_elapsed(&start_time);
   11326           0 :         kbytes = (double)torture_blocksize * torture_numops;
   11327           0 :         kbytes /= 1024;
   11328             : 
   11329           0 :         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
   11330           0 :                (double)seconds, (int)(kbytes/seconds));
   11331             : 
   11332           0 :         ret = true;
   11333           0 :  fail:
   11334           0 :         cli_close(cli1, fnum);
   11335           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11336           0 :         torture_close_connection(cli1);
   11337           0 :         return ret;
   11338             : }
   11339             : 
   11340          64 : static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
   11341             : {
   11342          64 :         size_t max_pdu = 0x1FFFF;
   11343             : 
   11344          64 :         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
   11345          32 :                 max_pdu = 0xFFFFFF;
   11346             :         }
   11347             : 
   11348          64 :         if (smb1cli_conn_signing_is_active(cli->conn)) {
   11349          32 :                 max_pdu = 0x1FFFF;
   11350             :         }
   11351             : 
   11352          64 :         if (smb1cli_conn_encryption_on(cli->conn)) {
   11353          16 :                 max_pdu = CLI_BUFFER_SIZE;
   11354             :         }
   11355             : 
   11356          64 :         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
   11357           8 :                 len_requested &= 0xFFFF;
   11358             :         }
   11359             : 
   11360          64 :         return MIN(len_requested,
   11361             :                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
   11362             : }
   11363             : 
   11364          64 : static bool check_read_call(struct cli_state *cli,
   11365             :                             uint16_t fnum,
   11366             :                             uint8_t *buf,
   11367             :                             size_t len_requested)
   11368             : {
   11369           0 :         NTSTATUS status;
   11370          64 :         struct tevent_req *subreq = NULL;
   11371          64 :         ssize_t len_read = 0;
   11372          64 :         size_t len_expected = 0;
   11373          64 :         struct tevent_context *ev = NULL;
   11374             : 
   11375          64 :         ev = samba_tevent_context_init(talloc_tos());
   11376          64 :         if (ev == NULL) {
   11377           0 :                 return false;
   11378             :         }
   11379             : 
   11380          64 :         subreq = cli_read_andx_send(talloc_tos(),
   11381             :                                     ev,
   11382             :                                     cli,
   11383             :                                     fnum,
   11384             :                                     0,
   11385             :                                     len_requested);
   11386             : 
   11387          64 :         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
   11388           0 :                 return false;
   11389             :         }
   11390             : 
   11391          64 :         status = cli_read_andx_recv(subreq, &len_read, &buf);
   11392          64 :         if (!NT_STATUS_IS_OK(status)) {
   11393           0 :                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
   11394           0 :                 return false;
   11395             :         }
   11396             : 
   11397          64 :         TALLOC_FREE(subreq);
   11398          64 :         TALLOC_FREE(ev);
   11399             : 
   11400          64 :         len_expected = calc_expected_return(cli, len_requested);
   11401             : 
   11402          64 :         if (len_expected > 0x10000 && len_read == 0x10000) {
   11403             :                 /* Windows servers only return a max of 0x10000,
   11404             :                    doesn't matter if you set CAP_LARGE_READX in
   11405             :                    the client sessionsetupX call or not. */
   11406          12 :                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
   11407             :                         (unsigned int)len_requested);
   11408          52 :         } else if (len_read != len_expected) {
   11409           0 :                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
   11410             :                         (unsigned int)len_requested,
   11411             :                         (unsigned int)len_read,
   11412             :                         (unsigned int)len_expected);
   11413           0 :                 return false;
   11414             :         } else {
   11415          52 :                 d_printf("Correct read reply.\n");
   11416             :         }
   11417             : 
   11418          64 :         return true;
   11419             : }
   11420             : 
   11421             : /* Test large readX variants. */
   11422           8 : static bool large_readx_tests(struct cli_state *cli,
   11423             :                                 uint16_t fnum,
   11424             :                                 uint8_t *buf)
   11425             : {
   11426             :         /* A read of 0xFFFF0001 should *always* return 1 byte. */
   11427           8 :         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
   11428           0 :                 return false;
   11429             :         }
   11430             :         /* A read of 0x10000 should return 0x10000 bytes. */
   11431           8 :         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
   11432           0 :                 return false;
   11433             :         }
   11434             :         /* A read of 0x10000 should return 0x10001 bytes. */
   11435           8 :         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
   11436           0 :                 return false;
   11437             :         }
   11438             :         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
   11439             :            the requested number of bytes. */
   11440           8 :         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
   11441           0 :                 return false;
   11442             :         }
   11443             :         /* A read of 1MB should return 1MB bytes (on Samba). */
   11444           8 :         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
   11445           0 :                 return false;
   11446             :         }
   11447             : 
   11448           8 :         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
   11449           0 :                 return false;
   11450             :         }
   11451           8 :         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
   11452           0 :                 return false;
   11453             :         }
   11454           8 :         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
   11455           0 :                 return false;
   11456             :         }
   11457           8 :         return true;
   11458             : }
   11459             : 
   11460           5 : static bool run_large_readx(int dummy)
   11461             : {
   11462           5 :         uint8_t *buf = NULL;
   11463           5 :         struct cli_state *cli1 = NULL;
   11464           5 :         struct cli_state *cli2 = NULL;
   11465           5 :         bool correct = false;
   11466           5 :         const char *fname = "\\large_readx.dat";
   11467           0 :         NTSTATUS status;
   11468           5 :         uint16_t fnum1 = UINT16_MAX;
   11469           5 :         uint32_t normal_caps = 0;
   11470           5 :         size_t file_size = 20*1024*1024;
   11471           5 :         TALLOC_CTX *frame = talloc_stackframe();
   11472           0 :         size_t i;
   11473           0 :         struct {
   11474             :                 const char *name;
   11475             :                 enum smb_signing_setting signing_setting;
   11476             :                 enum protocol_types protocol;
   11477           5 :         } runs[] = {
   11478             :                 {
   11479             :                         .name = "NT1",
   11480             :                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
   11481             :                         .protocol = PROTOCOL_NT1,
   11482             :                 },{
   11483             :                         .name = "NT1 - SIGNING_REQUIRED",
   11484             :                         .signing_setting = SMB_SIGNING_REQUIRED,
   11485             :                         .protocol = PROTOCOL_NT1,
   11486             :                 },
   11487             :         };
   11488             : 
   11489           5 :         printf("starting large_readx test\n");
   11490             : 
   11491           5 :         if (!torture_open_connection(&cli1, 0)) {
   11492           0 :                 goto out;
   11493             :         }
   11494             : 
   11495           5 :         normal_caps = smb1cli_conn_capabilities(cli1->conn);
   11496             : 
   11497           5 :         if (!(normal_caps & CAP_LARGE_READX)) {
   11498           0 :                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11499             :                         (unsigned int)normal_caps);
   11500           0 :                 goto out;
   11501             :         }
   11502             : 
   11503             :         /* Create a file of size 4MB. */
   11504           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
   11505             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11506             :                         0, 0, &fnum1, NULL);
   11507             : 
   11508           5 :         if (!NT_STATUS_IS_OK(status)) {
   11509           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11510           0 :                 goto out;
   11511             :         }
   11512             : 
   11513             :         /* Write file_size bytes. */
   11514           5 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11515           5 :         if (buf == NULL) {
   11516           0 :                 goto out;
   11517             :         }
   11518             : 
   11519           5 :         status = cli_writeall(cli1,
   11520             :                               fnum1,
   11521             :                               0,
   11522             :                               buf,
   11523             :                               0,
   11524             :                               file_size,
   11525             :                               NULL);
   11526           5 :         if (!NT_STATUS_IS_OK(status)) {
   11527           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11528           0 :                 goto out;
   11529             :         }
   11530             : 
   11531           5 :         status = cli_close(cli1, fnum1);
   11532           5 :         if (!NT_STATUS_IS_OK(status)) {
   11533           0 :                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11534           0 :                 goto out;
   11535             :         }
   11536             : 
   11537           5 :         fnum1 = UINT16_MAX;
   11538             : 
   11539          15 :         for (i=0; i < ARRAY_SIZE(runs); i++) {
   11540          10 :                 enum smb_signing_setting saved_signing_setting = signing_state;
   11541          10 :                 uint16_t fnum2 = -1;
   11542             : 
   11543          10 :                 if (do_encrypt &&
   11544           4 :                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
   11545             :                 {
   11546           2 :                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
   11547           2 :                         continue;
   11548             :                 }
   11549             : 
   11550           8 :                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
   11551             : 
   11552           8 :                 signing_state = runs[i].signing_setting;
   11553           8 :                 cli2 = open_nbt_connection();
   11554           8 :                 signing_state = saved_signing_setting;
   11555           8 :                 if (cli2 == NULL) {
   11556           0 :                         goto out;
   11557             :                 }
   11558             : 
   11559           8 :                 status = smbXcli_negprot(cli2->conn,
   11560           8 :                                          cli2->timeout,
   11561             :                                          runs[i].protocol,
   11562             :                                          runs[i].protocol,
   11563             :                                          NULL,
   11564             :                                          NULL,
   11565             :                                          NULL);
   11566           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11567           0 :                         goto out;
   11568             :                 }
   11569             : 
   11570           8 :                 status = cli_session_setup_creds(cli2, torture_creds);
   11571           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11572           0 :                         goto out;
   11573             :                 }
   11574             : 
   11575           8 :                 status = cli_tree_connect(cli2,
   11576             :                                         share,
   11577             :                                         "?????",
   11578             :                                         password);
   11579           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11580           0 :                         goto out;
   11581             :                 }
   11582             : 
   11583           8 :                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
   11584             : 
   11585           8 :                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
   11586             : 
   11587           8 :                 if (!(normal_caps & CAP_LARGE_READX)) {
   11588           0 :                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11589             :                                 (unsigned int)normal_caps);
   11590           0 :                         goto out;
   11591             :                 }
   11592             : 
   11593           8 :                 if (do_encrypt) {
   11594           2 :                         if (force_cli_encryption(cli2, share) == false) {
   11595           0 :                                 goto out;
   11596             :                         }
   11597           6 :                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
   11598           0 :                         uint16_t major, minor;
   11599           0 :                         uint32_t caplow, caphigh;
   11600             : 
   11601           4 :                         status = cli_unix_extensions_version(cli2,
   11602             :                                                              &major, &minor,
   11603             :                                                              &caplow, &caphigh);
   11604           4 :                         if (!NT_STATUS_IS_OK(status)) {
   11605           0 :                                 goto out;
   11606             :                         }
   11607             :                 }
   11608             : 
   11609           8 :                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
   11610             :                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
   11611             :                                 0, 0, &fnum2, NULL);
   11612           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11613           0 :                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
   11614           0 :                         goto out;
   11615             :                 }
   11616             : 
   11617             :                 /* All reads must return less than file_size bytes. */
   11618           8 :                 if (!large_readx_tests(cli2, fnum2, buf)) {
   11619           0 :                         goto out;
   11620             :                 }
   11621             : 
   11622           8 :                 status = cli_close(cli2, fnum2);
   11623           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11624           0 :                         d_printf("cli_close failed: %s\n", nt_errstr(status));
   11625           0 :                         goto out;
   11626             :                 }
   11627           8 :                 fnum2 = -1;
   11628             : 
   11629           8 :                 if (!torture_close_connection(cli2)) {
   11630           0 :                         goto out;
   11631             :                 }
   11632           8 :                 cli2 = NULL;
   11633             :         }
   11634             : 
   11635           5 :         correct = true;
   11636           5 :         printf("Success on large_readx test\n");
   11637             : 
   11638           5 :   out:
   11639             : 
   11640           5 :         if (cli2) {
   11641           0 :                 if (!torture_close_connection(cli2)) {
   11642           0 :                         correct = false;
   11643             :                 }
   11644             :         }
   11645             : 
   11646           5 :         if (cli1) {
   11647           5 :                 if (fnum1 != UINT16_MAX) {
   11648           0 :                         status = cli_close(cli1, fnum1);
   11649           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11650           0 :                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11651             :                         }
   11652           0 :                         fnum1 = UINT16_MAX;
   11653             :                 }
   11654             : 
   11655           5 :                 status = cli_unlink(cli1, fname,
   11656             :                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11657           5 :                 if (!NT_STATUS_IS_OK(status)) {
   11658           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
   11659             :                 }
   11660             : 
   11661           5 :                 if (!torture_close_connection(cli1)) {
   11662           0 :                         correct = false;
   11663             :                 }
   11664             :         }
   11665             : 
   11666           5 :         TALLOC_FREE(frame);
   11667             : 
   11668           5 :         printf("finished large_readx test\n");
   11669           5 :         return correct;
   11670             : }
   11671             : 
   11672          24 : static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
   11673             :                                   const char *mask,
   11674             :                                   void *private_data)
   11675             : {
   11676          24 :         uint32_t *p_attr = (uint32_t *)private_data;
   11677             : 
   11678          24 :         if (strequal(finfo->name, test_filename)) {
   11679           4 :                 *p_attr = finfo->attr;
   11680             :         }
   11681             : 
   11682          24 :         return NT_STATUS_OK;
   11683             : }
   11684             : 
   11685           4 : static bool run_msdfs_attribute(int dummy)
   11686             : {
   11687           0 :         static struct cli_state *cli;
   11688           4 :         bool correct = false;
   11689           4 :         uint32_t attr = 0;
   11690           0 :         NTSTATUS status;
   11691             : 
   11692           4 :         printf("Starting MSDFS-ATTRIBUTE test\n");
   11693             : 
   11694           4 :         if (test_filename == NULL || test_filename[0] == '\0') {
   11695           0 :                 printf("MSDFS-ATTRIBUTE test "
   11696             :                         "needs -f filename-of-msdfs-link\n");
   11697           0 :                 return false;
   11698             :         }
   11699             : 
   11700             :         /*
   11701             :          * NB. We use torture_open_connection_flags() not
   11702             :          * torture_open_connection() as the latter forces
   11703             :          * SMB1.
   11704             :          */
   11705           4 :         if (!torture_open_connection_flags(&cli, 0, 0)) {
   11706           0 :                 return false;
   11707             :         }
   11708             : 
   11709           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11710             : 
   11711           4 :         status = cli_list(cli,
   11712             :                         "*",
   11713             :                         FILE_ATTRIBUTE_DIRECTORY,
   11714             :                         msdfs_attribute_list_fn,
   11715             :                         &attr);
   11716             : 
   11717           4 :         if (!NT_STATUS_IS_OK(status)) {
   11718           0 :                 printf("cli_list failed with %s\n",
   11719             :                         nt_errstr(status));
   11720           0 :                 goto out;
   11721             :         }
   11722           4 :         if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
   11723           0 :                 printf("file %s should have "
   11724             :                         "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
   11725             :                         test_filename,
   11726             :                         (unsigned int)attr);
   11727           0 :                 goto out;
   11728             :         }
   11729             : 
   11730           4 :         if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
   11731           0 :                 printf("file %s should have "
   11732             :                         "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
   11733             :                         test_filename,
   11734             :                         (unsigned int)attr);
   11735           0 :                 goto out;
   11736             :         }
   11737             : 
   11738           4 :         correct = true;
   11739             : 
   11740           4 :   out:
   11741             : 
   11742           4 :         torture_close_connection(cli);
   11743           4 :         return correct;
   11744             : }
   11745             : 
   11746           0 : static bool run_cli_echo(int dummy)
   11747             : {
   11748           0 :         struct cli_state *cli;
   11749           0 :         NTSTATUS status;
   11750             : 
   11751           0 :         printf("starting cli_echo test\n");
   11752           0 :         if (!torture_open_connection(&cli, 0)) {
   11753           0 :                 return false;
   11754             :         }
   11755           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11756             : 
   11757           0 :         status = cli_echo(cli, 5, data_blob_const("hello", 5));
   11758             : 
   11759           0 :         d_printf("cli_echo returned %s\n", nt_errstr(status));
   11760             : 
   11761           0 :         torture_close_connection(cli);
   11762           0 :         return NT_STATUS_IS_OK(status);
   11763             : }
   11764             : 
   11765          14 : static int splice_status(off_t written, void *priv)
   11766             : {
   11767          14 :         return true;
   11768             : }
   11769             : 
   11770           7 : static bool run_cli_splice(int dummy)
   11771             : {
   11772           7 :         uint8_t *buf = NULL;
   11773           7 :         struct cli_state *cli1 = NULL;
   11774           7 :         bool correct = false;
   11775           7 :         const char *fname_src = "\\splice_src.dat";
   11776           7 :         const char *fname_dst = "\\splice_dst.dat";
   11777           0 :         NTSTATUS status;
   11778           7 :         uint16_t fnum1 = UINT16_MAX;
   11779           7 :         uint16_t fnum2 = UINT16_MAX;
   11780           7 :         size_t file_size = 2*1024*1024;
   11781           7 :         size_t splice_size = 1*1024*1024 + 713;
   11782           0 :         uint8_t digest1[16], digest2[16];
   11783           7 :         off_t written = 0;
   11784           7 :         size_t nread = 0;
   11785           7 :         TALLOC_CTX *frame = talloc_stackframe();
   11786             : 
   11787           7 :         printf("starting cli_splice test\n");
   11788             : 
   11789           7 :         if (!torture_open_connection(&cli1, 0)) {
   11790           0 :                 goto out;
   11791             :         }
   11792             : 
   11793           7 :         cli_unlink(cli1, fname_src,
   11794             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11795           7 :         cli_unlink(cli1, fname_dst,
   11796             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11797             : 
   11798             :         /* Create a file */
   11799           7 :         status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
   11800             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11801             :                         0, 0, &fnum1, NULL);
   11802             : 
   11803           7 :         if (!NT_STATUS_IS_OK(status)) {
   11804           0 :                 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
   11805           0 :                 goto out;
   11806             :         }
   11807             : 
   11808             :         /* Write file_size bytes - must be bigger than splice_size. */
   11809           7 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11810           7 :         if (buf == NULL) {
   11811           0 :                 d_printf("talloc_fail\n");
   11812           0 :                 goto out;
   11813             :         }
   11814             : 
   11815             :         /* Fill it with random numbers. */
   11816           7 :         generate_random_buffer(buf, file_size);
   11817             : 
   11818             :         /* MD5 the first 1MB + 713 bytes. */
   11819           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11820             :                          buf,
   11821             :                          splice_size,
   11822             :                          digest1);
   11823             : 
   11824           7 :         status = cli_writeall(cli1,
   11825             :                               fnum1,
   11826             :                               0,
   11827             :                               buf,
   11828             :                               0,
   11829             :                               file_size,
   11830             :                               NULL);
   11831           7 :         if (!NT_STATUS_IS_OK(status)) {
   11832           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11833           0 :                 goto out;
   11834             :         }
   11835             : 
   11836           7 :         status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
   11837             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11838             :                         0, 0, &fnum2, NULL);
   11839             : 
   11840           7 :         if (!NT_STATUS_IS_OK(status)) {
   11841           0 :                 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
   11842           0 :                 goto out;
   11843             :         }
   11844             : 
   11845             :         /* Now splice 1MB + 713 bytes. */
   11846           7 :         status = cli_splice(cli1,
   11847             :                                 cli1,
   11848             :                                 fnum1,
   11849             :                                 fnum2,
   11850             :                                 splice_size,
   11851             :                                 0,
   11852             :                                 0,
   11853             :                                 &written,
   11854             :                                 splice_status,
   11855             :                                 NULL);
   11856             : 
   11857           7 :         if (!NT_STATUS_IS_OK(status)) {
   11858           0 :                 d_printf("cli_splice failed: %s\n", nt_errstr(status));
   11859           0 :                 goto out;
   11860             :         }
   11861             : 
   11862             :         /* Clear the old buffer. */
   11863           7 :         memset(buf, '\0', file_size);
   11864             : 
   11865             :         /* Read the new file. */
   11866           7 :         status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
   11867           7 :         if (!NT_STATUS_IS_OK(status)) {
   11868           0 :                 d_printf("cli_read failed: %s\n", nt_errstr(status));
   11869           0 :                 goto out;
   11870             :         }
   11871           7 :         if (nread != splice_size) {
   11872           0 :                 d_printf("bad read of 0x%x, should be 0x%x\n",
   11873             :                         (unsigned int)nread,
   11874             :                         (unsigned int)splice_size);
   11875           0 :                 goto out;
   11876             :         }
   11877             : 
   11878             :         /* MD5 the first 1MB + 713 bytes. */
   11879           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11880             :                          buf,
   11881             :                          splice_size,
   11882             :                          digest2);
   11883             : 
   11884             :         /* Must be the same. */
   11885           7 :         if (memcmp(digest1, digest2, 16) != 0) {
   11886           0 :                 d_printf("bad MD5 compare\n");
   11887           0 :                 goto out;
   11888             :         }
   11889             : 
   11890           7 :         correct = true;
   11891           7 :         printf("Success on cli_splice test\n");
   11892             : 
   11893           7 :   out:
   11894             : 
   11895           7 :         if (cli1) {
   11896           7 :                 if (fnum1 != UINT16_MAX) {
   11897           7 :                         cli_close(cli1, fnum1);
   11898             :                 }
   11899           7 :                 if (fnum2 != UINT16_MAX) {
   11900           7 :                         cli_close(cli1, fnum2);
   11901             :                 }
   11902             : 
   11903           7 :                 cli_unlink(cli1, fname_src,
   11904             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11905           7 :                 cli_unlink(cli1, fname_dst,
   11906             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11907             : 
   11908           7 :                 if (!torture_close_connection(cli1)) {
   11909           0 :                         correct = false;
   11910             :                 }
   11911             :         }
   11912             : 
   11913           7 :         TALLOC_FREE(frame);
   11914           7 :         return correct;
   11915             : }
   11916             : 
   11917           4 : static bool run_uid_regression_test(int dummy)
   11918             : {
   11919           0 :         static struct cli_state *cli;
   11920           0 :         int16_t old_vuid;
   11921           0 :         int32_t old_cnum;
   11922           4 :         bool correct = True;
   11923           4 :         struct smbXcli_tcon *tcon_copy = NULL;
   11924           0 :         NTSTATUS status;
   11925             : 
   11926           4 :         printf("starting uid regression test\n");
   11927             : 
   11928           4 :         if (!torture_open_connection(&cli, 0)) {
   11929           0 :                 return False;
   11930             :         }
   11931             : 
   11932           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11933             : 
   11934             :         /* Ok - now save then logoff our current user. */
   11935           4 :         old_vuid = cli_state_get_uid(cli);
   11936             : 
   11937           4 :         status = cli_ulogoff(cli);
   11938           4 :         if (!NT_STATUS_IS_OK(status)) {
   11939           0 :                 d_printf("(%s) cli_ulogoff failed: %s\n",
   11940             :                          __location__, nt_errstr(status));
   11941           0 :                 correct = false;
   11942           0 :                 goto out;
   11943             :         }
   11944             : 
   11945           4 :         cli_state_set_uid(cli, old_vuid);
   11946             : 
   11947             :         /* Try an operation. */
   11948           4 :         status = cli_mkdir(cli, "\\uid_reg_test");
   11949           4 :         if (NT_STATUS_IS_OK(status)) {
   11950           0 :                 d_printf("(%s) cli_mkdir succeeded\n",
   11951             :                          __location__);
   11952           0 :                 correct = false;
   11953           0 :                 goto out;
   11954             :         } else {
   11955             :                 /* Should be bad uid. */
   11956           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
   11957           4 :                                  NT_STATUS_USER_SESSION_DELETED)) {
   11958           0 :                         correct = false;
   11959           0 :                         goto out;
   11960             :                 }
   11961             :         }
   11962             : 
   11963           4 :         old_cnum = cli_state_get_tid(cli);
   11964             :         /*
   11965             :          * This is an SMB1-only test.
   11966             :          * Copy the tcon, not "save/restore".
   11967             :          *
   11968             :          * In SMB1 the cli_tdis() below frees
   11969             :          * cli->smb1.tcon so we need a copy
   11970             :          * of the struct to put back for the
   11971             :          * second tdis call with invalid vuid.
   11972             :          *
   11973             :          * This is a test-only hack. Real client code
   11974             :          * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
   11975             :          */
   11976           4 :         tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
   11977           4 :         if (tcon_copy == NULL) {
   11978           0 :                 correct = false;
   11979           0 :                 goto out;
   11980             :         }
   11981             : 
   11982             :         /* Now try a SMBtdis with the invalid vuid set to zero. */
   11983           4 :         cli_state_set_uid(cli, 0);
   11984             : 
   11985             :         /* This should succeed. */
   11986           4 :         status = cli_tdis(cli);
   11987             : 
   11988           4 :         if (NT_STATUS_IS_OK(status)) {
   11989           4 :                 d_printf("First tdis with invalid vuid should succeed.\n");
   11990             :         } else {
   11991           0 :                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
   11992           0 :                 correct = false;
   11993           0 :                 cli->smb1.tcon = tcon_copy;
   11994           0 :                 goto out;
   11995             :         }
   11996             : 
   11997           4 :         cli->smb1.tcon = tcon_copy;
   11998           4 :         cli_state_set_uid(cli, old_vuid);
   11999           4 :         cli_state_set_tid(cli, old_cnum);
   12000             : 
   12001             :         /* This should fail. */
   12002           4 :         status = cli_tdis(cli);
   12003           4 :         if (NT_STATUS_IS_OK(status)) {
   12004           0 :                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
   12005           0 :                 correct = false;
   12006           0 :                 goto out;
   12007             :         } else {
   12008             :                 /* Should be bad tid. */
   12009           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
   12010           4 :                                 NT_STATUS_NETWORK_NAME_DELETED)) {
   12011           0 :                         correct = false;
   12012           0 :                         goto out;
   12013             :                 }
   12014             :         }
   12015             : 
   12016           4 :         cli_rmdir(cli, "\\uid_reg_test");
   12017             : 
   12018           4 :   out:
   12019             : 
   12020           4 :         cli_shutdown(cli);
   12021           4 :         return correct;
   12022             : }
   12023             : 
   12024             : 
   12025             : static const char *illegal_chars = "*\\/?<>|\":";
   12026             : static char force_shortname_chars[] = " +,.[];=\177";
   12027             : 
   12028           8 : static NTSTATUS shortname_del_fn(struct file_info *finfo,
   12029             :                              const char *mask, void *state)
   12030             : {
   12031           8 :         struct cli_state *pcli = (struct cli_state *)state;
   12032           0 :         fstring fname;
   12033           8 :         NTSTATUS status = NT_STATUS_OK;
   12034             : 
   12035           8 :         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
   12036             : 
   12037           8 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
   12038           8 :                 return NT_STATUS_OK;
   12039             : 
   12040           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
   12041           0 :                 status = cli_rmdir(pcli, fname);
   12042           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12043           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
   12044             :                 }
   12045             :         } else {
   12046           0 :                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12047           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12048           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
   12049             :                 }
   12050             :         }
   12051           0 :         return status;
   12052             : }
   12053             : 
   12054             : struct sn_state {
   12055             :         int matched;
   12056             :         int i;
   12057             :         bool val;
   12058             : };
   12059             : 
   12060         348 : static NTSTATUS shortname_list_fn(struct file_info *finfo,
   12061             :                               const char *name, void *state)
   12062             : {
   12063         348 :         struct sn_state *s = (struct sn_state  *)state;
   12064         348 :         int i = s->i;
   12065             : 
   12066             : #if 0
   12067             :         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
   12068             :                 i, finfo->name, finfo->short_name);
   12069             : #endif
   12070             : 
   12071         348 :         if (strchr(force_shortname_chars, i)) {
   12072          36 :                 if (!finfo->short_name) {
   12073             :                         /* Shortname not created when it should be. */
   12074           0 :                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
   12075             :                                 __location__, finfo->name, i);
   12076           0 :                         s->val = true;
   12077             :                 }
   12078         312 :         } else if (finfo->short_name){
   12079             :                 /* Shortname created when it should not be. */
   12080           0 :                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
   12081             :                         __location__, finfo->short_name, finfo->name);
   12082           0 :                 s->val = true;
   12083             :         }
   12084         348 :         s->matched += 1;
   12085         348 :         return NT_STATUS_OK;
   12086             : }
   12087             : 
   12088           4 : static bool run_shortname_test(int dummy)
   12089             : {
   12090           0 :         static struct cli_state *cli;
   12091           4 :         bool correct = True;
   12092           0 :         int i;
   12093           0 :         struct sn_state s;
   12094           0 :         char fname[40];
   12095           0 :         NTSTATUS status;
   12096             : 
   12097           4 :         printf("starting shortname test\n");
   12098             : 
   12099           4 :         if (!torture_open_connection(&cli, 0)) {
   12100           0 :                 return False;
   12101             :         }
   12102             : 
   12103           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12104             : 
   12105           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12106           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12107           4 :         cli_rmdir(cli, "\\shortname");
   12108             : 
   12109           4 :         status = cli_mkdir(cli, "\\shortname");
   12110           4 :         if (!NT_STATUS_IS_OK(status)) {
   12111           0 :                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
   12112             :                         __location__, nt_errstr(status));
   12113           0 :                 correct = false;
   12114           0 :                 goto out;
   12115             :         }
   12116             : 
   12117           4 :         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
   12118           0 :                 correct = false;
   12119           0 :                 goto out;
   12120             :         }
   12121           4 :         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
   12122           0 :                 correct = false;
   12123           0 :                 goto out;
   12124             :         }
   12125             : 
   12126           4 :         s.val = false;
   12127             : 
   12128         388 :         for (i = 32; i < 128; i++) {
   12129         384 :                 uint16_t fnum = (uint16_t)-1;
   12130             : 
   12131         384 :                 s.i = i;
   12132             : 
   12133         384 :                 if (strchr(illegal_chars, i)) {
   12134          36 :                         continue;
   12135             :                 }
   12136         348 :                 fname[15] = i;
   12137             : 
   12138         348 :                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
   12139             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
   12140             :                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
   12141         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12142           0 :                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
   12143             :                                 __location__, fname, nt_errstr(status));
   12144           0 :                         correct = false;
   12145           0 :                         goto out;
   12146             :                 }
   12147         348 :                 cli_close(cli, fnum);
   12148             : 
   12149         348 :                 s.matched = 0;
   12150         348 :                 status = cli_list(cli, "\\shortname\\test*.*", 0,
   12151             :                                   shortname_list_fn, &s);
   12152         348 :                 if (s.matched != 1) {
   12153           0 :                         d_printf("(%s) failed to list %s: %s\n",
   12154             :                                 __location__, fname, nt_errstr(status));
   12155           0 :                         correct = false;
   12156           0 :                         goto out;
   12157             :                 }
   12158             : 
   12159         348 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12160         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12161           0 :                         d_printf("(%s) failed to delete %s: %s\n",
   12162             :                                 __location__, fname, nt_errstr(status));
   12163           0 :                         correct = false;
   12164           0 :                         goto out;
   12165             :                 }
   12166             : 
   12167         348 :                 if (s.val) {
   12168           0 :                         correct = false;
   12169           0 :                         goto out;
   12170             :                 }
   12171             :         }
   12172             : 
   12173           4 :   out:
   12174             : 
   12175           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12176           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12177           4 :         cli_rmdir(cli, "\\shortname");
   12178           4 :         torture_close_connection(cli);
   12179           4 :         return correct;
   12180             : }
   12181             : 
   12182             : TLDAPRC callback_code;
   12183             : 
   12184         478 : static void pagedsearch_cb(struct tevent_req *req)
   12185             : {
   12186           0 :         TLDAPRC rc;
   12187           0 :         struct tldap_message *msg;
   12188           0 :         char *dn;
   12189             : 
   12190         478 :         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
   12191         478 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12192           0 :                 d_printf("tldap_search_paged_recv failed: %s\n",
   12193             :                          tldap_rc2string(rc));
   12194           0 :                 callback_code = rc;
   12195           0 :                 return;
   12196             :         }
   12197         478 :         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
   12198           8 :                 TALLOC_FREE(msg);
   12199           8 :                 return;
   12200             :         }
   12201         470 :         if (!tldap_entry_dn(msg, &dn)) {
   12202           0 :                 d_printf("tldap_entry_dn failed\n");
   12203           0 :                 return;
   12204             :         }
   12205         470 :         d_printf("%s\n", dn);
   12206         470 :         TALLOC_FREE(msg);
   12207             : }
   12208             : 
   12209             : enum tldap_extended_val {
   12210             :         EXTENDED_ZERO = 0,
   12211             :         EXTENDED_ONE = 1,
   12212             :         EXTENDED_NONE = 2,
   12213             : };
   12214             : 
   12215             : /*
   12216             :  * Construct an extended dn control with either no value, 0 or 1
   12217             :  *
   12218             :  * No value and 0 are equivalent (non-hyphenated GUID)
   12219             :  * 1 has the hyphenated GUID
   12220             :  */
   12221             : static struct tldap_control *
   12222           6 : tldap_build_extended_control(enum tldap_extended_val val)
   12223             : {
   12224           0 :         struct tldap_control empty_control;
   12225           0 :         struct asn1_data *data;
   12226             : 
   12227           6 :         ZERO_STRUCT(empty_control);
   12228             : 
   12229           6 :         if (val != EXTENDED_NONE) {
   12230           4 :                 data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
   12231             : 
   12232           4 :                 if (!data) {
   12233           0 :                         return NULL;
   12234             :                 }
   12235             : 
   12236           4 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
   12237           0 :                         return NULL;
   12238             :                 }
   12239             : 
   12240           4 :                 if (!asn1_write_Integer(data, (int)val)) {
   12241           0 :                         return NULL;
   12242             :                 }
   12243             : 
   12244           4 :                 if (!asn1_pop_tag(data)) {
   12245           0 :                         return NULL;
   12246             :                 }
   12247             : 
   12248           4 :                 if (!asn1_blob(data, &empty_control.value)) {
   12249           0 :                         return NULL;
   12250             :                 }
   12251             :         }
   12252             : 
   12253           6 :         empty_control.oid = "1.2.840.113556.1.4.529";
   12254           6 :         empty_control.critical = true;
   12255             : 
   12256           6 :         return tldap_add_control(talloc_tos(), NULL, 0, &empty_control);
   12257             : 
   12258             : }
   12259             : 
   12260           6 : static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn,
   12261             :                                       enum tldap_extended_val control_val)
   12262             : {
   12263           6 :         struct tldap_control *control = tldap_build_extended_control(control_val);
   12264           6 :         char *dn = NULL;
   12265           0 :         struct tldap_message **msg;
   12266           0 :         TLDAPRC rc;
   12267             : 
   12268           6 :         rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE,
   12269             :                           "(objectClass=*)", NULL, 0, 0,
   12270             :                           control, 1, NULL,
   12271             :                           0, 0, 0, 0, talloc_tos(), &msg);
   12272           6 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12273           0 :                 d_printf("tldap_search for domain DN failed: %s\n",
   12274             :                          tldap_errstr(talloc_tos(), ld, rc));
   12275           0 :                 return false;
   12276             :         }
   12277             : 
   12278           6 :         if (!tldap_entry_dn(msg[0], &dn)) {
   12279           0 :                 d_printf("tldap_search domain DN fetch failed: %s\n",
   12280             :                          tldap_errstr(talloc_tos(), ld, rc));
   12281           0 :                 return false;
   12282             :         }
   12283             : 
   12284           6 :         d_printf("%s\n", dn);
   12285             :         {
   12286           0 :                 uint32_t time_low;
   12287           0 :                 uint32_t time_mid, time_hi_and_version;
   12288           0 :                 uint32_t clock_seq[2];
   12289           0 :                 uint32_t node[6];
   12290           0 :                 char next;
   12291             : 
   12292           6 :                 switch (control_val) {
   12293           4 :                 case EXTENDED_NONE:
   12294             :                 case EXTENDED_ZERO:
   12295             :                         /*
   12296             :                          * When reading GUIDs with hyphens, scanf will treat
   12297             :                          * hyphen as a hex character (and counts as part of the
   12298             :                          * width). This creates leftover GUID string which we
   12299             :                          * check will for with 'next' and closing '>'.
   12300             :                          */
   12301           4 :                         if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
   12302             :                                          &time_low, &time_mid,
   12303             :                                          &time_hi_and_version, &clock_seq[0],
   12304             :                                          &clock_seq[1], &node[0], &node[1],
   12305             :                                          &node[2], &node[3], &node[4],
   12306             :                                          &node[5], &next)) {
   12307             :                                 /* This GUID is good */
   12308             :                         } else {
   12309           0 :                                 d_printf("GUID format in control (no hyphens) doesn't match output\n");
   12310           0 :                                 return false;
   12311             :                         }
   12312             : 
   12313           4 :                         break;
   12314           2 :                 case EXTENDED_ONE:
   12315           2 :                         if (12 == sscanf(dn,
   12316             :                                          "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
   12317             :                                          &time_low, &time_mid,
   12318             :                                          &time_hi_and_version, &clock_seq[0],
   12319             :                                          &clock_seq[1], &node[0], &node[1],
   12320             :                                          &node[2], &node[3], &node[4],
   12321             :                                          &node[5], &next)) {
   12322             :                                 /* This GUID is good */
   12323             :                         } else {
   12324           0 :                                 d_printf("GUID format in control (with hyphens) doesn't match output\n");
   12325           0 :                                 return false;
   12326             :                         }
   12327             : 
   12328           2 :                         break;
   12329           0 :                 default:
   12330           0 :                         return false;
   12331             :                 }
   12332             :         }
   12333             : 
   12334           6 :         return true;
   12335             : }
   12336             : 
   12337           2 : static bool run_tldap(int dummy)
   12338             : {
   12339           0 :         struct tldap_context *ld;
   12340           0 :         int fd;
   12341           0 :         TLDAPRC rc;
   12342           0 :         NTSTATUS status;
   12343           0 :         struct sockaddr_storage addr;
   12344           0 :         struct tevent_context *ev;
   12345           0 :         struct tevent_req *req;
   12346           0 :         char *basedn;
   12347           0 :         const char *filter;
   12348             : 
   12349           2 :         if (!resolve_name(host, &addr, 0, false)) {
   12350           0 :                 d_printf("could not find host %s\n", host);
   12351           0 :                 return false;
   12352             :         }
   12353           2 :         status = open_socket_out(&addr, 389, 9999, &fd);
   12354           2 :         if (!NT_STATUS_IS_OK(status)) {
   12355           0 :                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
   12356           0 :                 return false;
   12357             :         }
   12358             : 
   12359           2 :         ld = tldap_context_create(talloc_tos(), fd);
   12360           2 :         if (ld == NULL) {
   12361           0 :                 close(fd);
   12362           0 :                 d_printf("tldap_context_create failed\n");
   12363           0 :                 return false;
   12364             :         }
   12365             : 
   12366           2 :         rc = tldap_fetch_rootdse(ld);
   12367           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12368           0 :                 d_printf("tldap_fetch_rootdse failed: %s\n",
   12369             :                          tldap_errstr(talloc_tos(), ld, rc));
   12370           0 :                 return false;
   12371             :         }
   12372             : 
   12373           2 :         basedn = tldap_talloc_single_attribute(
   12374             :                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
   12375           2 :         if (basedn == NULL) {
   12376           0 :                 d_printf("no defaultNamingContext\n");
   12377           0 :                 return false;
   12378             :         }
   12379           2 :         d_printf("defaultNamingContext: %s\n", basedn);
   12380             : 
   12381           2 :         ev = samba_tevent_context_init(talloc_tos());
   12382           2 :         if (ev == NULL) {
   12383           0 :                 d_printf("tevent_context_init failed\n");
   12384           0 :                 return false;
   12385             :         }
   12386             : 
   12387           2 :         rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL,
   12388             :                                loadparm_init_s3(talloc_tos(),
   12389             :                                                 loadparm_s3_helpers()),
   12390             :                                GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
   12391             : 
   12392           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12393           0 :                 d_printf("tldap_gensec_bind failed\n");
   12394           0 :                 return false;
   12395             :         }
   12396             : 
   12397           2 :         callback_code = TLDAP_SUCCESS;
   12398             : 
   12399           2 :         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
   12400             :                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
   12401             :                                       NULL, 0, 0,
   12402             :                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
   12403           2 :         if (req == NULL) {
   12404           0 :                 d_printf("tldap_search_paged_send failed\n");
   12405           0 :                 return false;
   12406             :         }
   12407           2 :         tevent_req_set_callback(req, pagedsearch_cb, NULL);
   12408             : 
   12409           2 :         tevent_req_poll(req, ev);
   12410             : 
   12411           2 :         TALLOC_FREE(req);
   12412             : 
   12413           2 :         rc = callback_code;
   12414             : 
   12415           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12416           0 :                 d_printf("tldap_search with paging failed: %s\n",
   12417             :                          tldap_errstr(talloc_tos(), ld, rc));
   12418           0 :                 return false;
   12419             :         }
   12420             : 
   12421             :         /* test search filters against rootDSE */
   12422           2 :         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
   12423             :                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
   12424             : 
   12425           2 :         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
   12426             :                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
   12427             :                           talloc_tos(), NULL);
   12428           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12429           0 :                 d_printf("tldap_search with complex filter failed: %s\n",
   12430             :                          tldap_errstr(talloc_tos(), ld, rc));
   12431           0 :                 return false;
   12432             :         }
   12433             : 
   12434             :         /*
   12435             :          * Tests to check for regression of:
   12436             :          *
   12437             :          * https://bugzilla.samba.org/show_bug.cgi?id=14029
   12438             :          *
   12439             :          * TLDAP used here to pick apart the original string DN (with GUID)
   12440             :          */
   12441           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) {
   12442           0 :                 d_printf("tldap_search with extended dn (no val) failed: %s\n",
   12443             :                          tldap_errstr(talloc_tos(), ld, rc));
   12444           0 :                 return false;
   12445             :         }
   12446           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) {
   12447           0 :                 d_printf("tldap_search with extended dn (0) failed: %s\n",
   12448             :                          tldap_errstr(talloc_tos(), ld, rc));
   12449           0 :                 return false;
   12450             :         }
   12451           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) {
   12452           0 :                 d_printf("tldap_search with extended dn (1) failed: %s\n",
   12453             :                          tldap_errstr(talloc_tos(), ld, rc));
   12454           0 :                 return false;
   12455             :         }
   12456             : 
   12457           2 :         TALLOC_FREE(ld);
   12458           2 :         return true;
   12459             : }
   12460             : 
   12461             : /* Torture test to ensure no regression of :
   12462             : https://bugzilla.samba.org/show_bug.cgi?id=7084
   12463             : */
   12464             : 
   12465           4 : static bool run_dir_createtime(int dummy)
   12466             : {
   12467           0 :         struct cli_state *cli;
   12468           4 :         const char *dname = "\\testdir_createtime";
   12469           4 :         const char *fname = "\\testdir_createtime\\testfile";
   12470           0 :         NTSTATUS status;
   12471           0 :         struct timespec create_time;
   12472           0 :         struct timespec create_time1;
   12473           0 :         uint16_t fnum;
   12474           4 :         bool ret = false;
   12475           0 :         uint64_t ino;
   12476             : 
   12477           4 :         if (!torture_open_connection(&cli, 0)) {
   12478           0 :                 return false;
   12479             :         }
   12480             : 
   12481           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12482             :                 /* Ensure ino is zero, SMB2 gets a real one. */
   12483           0 :                 ino = 0;
   12484             :         } else {
   12485             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
   12486           4 :                 ino = (uint64_t)-1;
   12487             :         }
   12488             : 
   12489           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12490           4 :         cli_rmdir(cli, dname);
   12491             : 
   12492           4 :         status = cli_mkdir(cli, dname);
   12493           4 :         if (!NT_STATUS_IS_OK(status)) {
   12494           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12495           0 :                 goto out;
   12496             :         }
   12497             : 
   12498           4 :         status = cli_qpathinfo2(cli,
   12499             :                                 dname,
   12500             :                                 &create_time,
   12501             :                                 NULL,
   12502             :                                 NULL,
   12503             :                                 NULL,
   12504             :                                 NULL,
   12505             :                                 NULL,
   12506             :                                 &ino,
   12507             :                                 NULL);
   12508           4 :         if (!NT_STATUS_IS_OK(status)) {
   12509           0 :                 printf("cli_qpathinfo2 returned %s\n",
   12510             :                        nt_errstr(status));
   12511           0 :                 goto out;
   12512             :         }
   12513             : 
   12514           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12515             :                 /* SMB2 should always return an inode. */
   12516           0 :                 if (ino == 0) {
   12517           0 :                         printf("SMB2 bad inode (0)\n");
   12518           0 :                         goto out;
   12519             :                 }
   12520             :         } else {
   12521             :                 /* SMB1 must always return zero here. */
   12522           4 :                 if (ino != 0) {
   12523           0 :                         printf("SMB1 bad inode (!0)\n");
   12524           0 :                         goto out;
   12525             :                 }
   12526             :         }
   12527             : 
   12528             :         /* Sleep 3 seconds, then create a file. */
   12529           4 :         sleep(3);
   12530             : 
   12531           4 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
   12532             :                          DENY_NONE, &fnum);
   12533           4 :         if (!NT_STATUS_IS_OK(status)) {
   12534           0 :                 printf("cli_openx failed: %s\n", nt_errstr(status));
   12535           0 :                 goto out;
   12536             :         }
   12537             : 
   12538           4 :         status = cli_qpathinfo2(cli,
   12539             :                                 dname,
   12540             :                                 &create_time1,
   12541             :                                 NULL,
   12542             :                                 NULL,
   12543             :                                 NULL,
   12544             :                                 NULL,
   12545             :                                 NULL,
   12546             :                                 NULL,
   12547             :                                 NULL);
   12548           4 :         if (!NT_STATUS_IS_OK(status)) {
   12549           0 :                 printf("cli_qpathinfo2 (2) returned %s\n",
   12550             :                        nt_errstr(status));
   12551           0 :                 goto out;
   12552             :         }
   12553             : 
   12554           4 :         if (timespec_compare(&create_time1, &create_time)) {
   12555           0 :                 printf("run_dir_createtime: create time was updated (error)\n");
   12556             :         } else {
   12557           4 :                 printf("run_dir_createtime: create time was not updated (correct)\n");
   12558           4 :                 ret = true;
   12559             :         }
   12560             : 
   12561           4 :   out:
   12562             : 
   12563           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12564           4 :         cli_rmdir(cli, dname);
   12565           4 :         if (!torture_close_connection(cli)) {
   12566           0 :                 ret = false;
   12567             :         }
   12568           4 :         return ret;
   12569             : }
   12570             : 
   12571             : 
   12572           4 : static bool run_streamerror(int dummy)
   12573             : {
   12574           0 :         struct cli_state *cli;
   12575           4 :         const char *dname = "\\testdir_streamerror";
   12576           4 :         const char *streamname =
   12577             :                 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
   12578           0 :         NTSTATUS status;
   12579           0 :         time_t change_time, access_time, write_time;
   12580           0 :         off_t size;
   12581           0 :         uint16_t fnum;
   12582           0 :         uint32_t attr;
   12583           4 :         bool ret = true;
   12584             : 
   12585           4 :         if (!torture_open_connection(&cli, 0)) {
   12586           0 :                 return false;
   12587             :         }
   12588             : 
   12589           4 :         torture_deltree(cli, dname);
   12590             : 
   12591           4 :         status = cli_mkdir(cli, dname);
   12592           4 :         if (!NT_STATUS_IS_OK(status)) {
   12593           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12594           0 :                 return false;
   12595             :         }
   12596             : 
   12597           4 :         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
   12598             :                                 &write_time, &size, &attr);
   12599           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12600           0 :                 printf("pathinfo returned %s, expected "
   12601             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12602             :                        nt_errstr(status));
   12603           0 :                 ret = false;
   12604             :         }
   12605             : 
   12606           4 :         status = cli_ntcreate(cli, streamname, 0x16,
   12607             :                               FILE_READ_DATA|FILE_READ_EA|
   12608             :                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
   12609             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
   12610             :                               FILE_OPEN, 0, 0, &fnum, NULL);
   12611             : 
   12612           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12613           0 :                 printf("ntcreate returned %s, expected "
   12614             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12615             :                        nt_errstr(status));
   12616           0 :                 ret = false;
   12617             :         }
   12618             : 
   12619             : 
   12620           4 :         cli_rmdir(cli, dname);
   12621           4 :         return ret;
   12622             : }
   12623             : 
   12624             : struct pidtest_state {
   12625             :         bool success;
   12626             :         uint16_t vwv[1];
   12627             :         DATA_BLOB data;
   12628             : };
   12629             : 
   12630             : static void pid_echo_done(struct tevent_req *subreq);
   12631             : 
   12632           4 : static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
   12633             :                         struct tevent_context *ev,
   12634             :                         struct cli_state *cli)
   12635             : {
   12636           0 :         struct tevent_req *req, *subreq;
   12637           0 :         struct pidtest_state *state;
   12638             : 
   12639           4 :         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
   12640           4 :         if (req == NULL) {
   12641           0 :                 return NULL;
   12642             :         }
   12643             : 
   12644           4 :         SSVAL(state->vwv, 0, 1);
   12645           4 :         state->data = data_blob_const("hello", 5);
   12646             : 
   12647           4 :         subreq = smb1cli_req_send(state,
   12648             :                                 ev,
   12649             :                                 cli->conn,
   12650             :                                 SMBecho,
   12651             :                                 0, 0, /* *_flags */
   12652             :                                 0, 0, /* *_flags2 */
   12653           4 :                                 cli->timeout,
   12654             :                                 0xDEADBEEF, /* pid */
   12655             :                                 NULL, /* tcon */
   12656             :                                 NULL, /* session */
   12657           4 :                                 ARRAY_SIZE(state->vwv), state->vwv,
   12658           4 :                                 state->data.length, state->data.data);
   12659             : 
   12660           4 :         if (tevent_req_nomem(subreq, req)) {
   12661           0 :                 return tevent_req_post(req, ev);
   12662             :         }
   12663           4 :         tevent_req_set_callback(subreq, pid_echo_done, req);
   12664           4 :         return req;
   12665             : }
   12666             : 
   12667           4 : static void pid_echo_done(struct tevent_req *subreq)
   12668             : {
   12669           4 :         struct tevent_req *req = tevent_req_callback_data(
   12670             :                 subreq, struct tevent_req);
   12671           4 :         struct pidtest_state *state = tevent_req_data(
   12672             :                 req, struct pidtest_state);
   12673           0 :         NTSTATUS status;
   12674           0 :         uint32_t num_bytes;
   12675           4 :         uint8_t *bytes = NULL;
   12676           4 :         struct iovec *recv_iov = NULL;
   12677           4 :         uint8_t *phdr = NULL;
   12678           4 :         uint16_t pidlow = 0;
   12679           4 :         uint16_t pidhigh = 0;
   12680           4 :         struct smb1cli_req_expected_response expected[] = {
   12681             :         {
   12682             :                 .status = NT_STATUS_OK,
   12683             :                 .wct    = 1,
   12684             :         },
   12685             :         };
   12686             : 
   12687           4 :         status = smb1cli_req_recv(subreq, state,
   12688             :                                 &recv_iov,
   12689             :                                 &phdr,
   12690             :                                 NULL, /* pwct */
   12691             :                                 NULL, /* pvwv */
   12692             :                                 NULL, /* pvwv_offset */
   12693             :                                 &num_bytes,
   12694             :                                 &bytes,
   12695             :                                 NULL, /* pbytes_offset */
   12696             :                                 NULL, /* pinbuf */
   12697             :                                 expected, ARRAY_SIZE(expected));
   12698             : 
   12699           4 :         TALLOC_FREE(subreq);
   12700             : 
   12701           4 :         if (!NT_STATUS_IS_OK(status)) {
   12702           0 :                 tevent_req_nterror(req, status);
   12703           0 :                 return;
   12704             :         }
   12705             : 
   12706           4 :         if (num_bytes != state->data.length) {
   12707           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12708           0 :                 return;
   12709             :         }
   12710             : 
   12711           4 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
   12712           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12713           0 :                 return;
   12714             :         }
   12715             : 
   12716             :         /* Check pid low/high == DEADBEEF */
   12717           4 :         pidlow = SVAL(phdr, HDR_PID);
   12718           4 :         if (pidlow != 0xBEEF){
   12719           0 :                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
   12720             :                         (unsigned int)pidlow);
   12721           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12722           0 :                 return;
   12723             :         }
   12724           4 :         pidhigh = SVAL(phdr, HDR_PIDHIGH);
   12725           4 :         if (pidhigh != 0xDEAD){
   12726           0 :                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
   12727             :                         (unsigned int)pidhigh);
   12728           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12729           0 :                 return;
   12730             :         }
   12731             : 
   12732           4 :         tevent_req_done(req);
   12733             : }
   12734             : 
   12735           4 : static NTSTATUS pid_echo_recv(struct tevent_req *req)
   12736             : {
   12737           4 :         return tevent_req_simple_recv_ntstatus(req);
   12738             : }
   12739             : 
   12740           4 : static bool run_pidhigh(int dummy)
   12741             : {
   12742           4 :         bool success = false;
   12743           4 :         struct cli_state *cli = NULL;
   12744           0 :         NTSTATUS status;
   12745           4 :         struct tevent_context *ev = NULL;
   12746           4 :         struct tevent_req *req = NULL;
   12747           4 :         TALLOC_CTX *frame = talloc_stackframe();
   12748             : 
   12749           4 :         printf("starting pid high test\n");
   12750           4 :         if (!torture_open_connection(&cli, 0)) {
   12751           0 :                 return false;
   12752             :         }
   12753           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12754             : 
   12755           4 :         ev = samba_tevent_context_init(frame);
   12756           4 :         if (ev == NULL) {
   12757           0 :                 goto fail;
   12758             :         }
   12759             : 
   12760           4 :         req = pid_echo_send(frame, ev, cli);
   12761           4 :         if (req == NULL) {
   12762           0 :                 goto fail;
   12763             :         }
   12764             : 
   12765           4 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
   12766           0 :                 goto fail;
   12767             :         }
   12768             : 
   12769           4 :         status = pid_echo_recv(req);
   12770           4 :         if (NT_STATUS_IS_OK(status)) {
   12771           4 :                 printf("pid high test ok\n");
   12772           4 :                 success = true;
   12773             :         }
   12774             : 
   12775           0 :  fail:
   12776             : 
   12777           4 :         TALLOC_FREE(frame);
   12778           4 :         torture_close_connection(cli);
   12779           4 :         return success;
   12780             : }
   12781             : 
   12782             : /*
   12783             :   Test Windows open on a bad POSIX symlink.
   12784             :  */
   12785           4 : static bool run_symlink_open_test(int dummy)
   12786             : {
   12787           0 :         static struct cli_state *cli;
   12788           4 :         const char *fname = "non_existant_file";
   12789           4 :         const char *sname = "dangling_symlink";
   12790           4 :         uint16_t fnum = (uint16_t)-1;
   12791           4 :         bool correct = false;
   12792           0 :         NTSTATUS status;
   12793           4 :         TALLOC_CTX *frame = NULL;
   12794             : 
   12795           4 :         frame = talloc_stackframe();
   12796             : 
   12797           4 :         printf("Starting Windows bad symlink open test\n");
   12798             : 
   12799           4 :         if (!torture_open_connection(&cli, 0)) {
   12800           0 :                 TALLOC_FREE(frame);
   12801           0 :                 return false;
   12802             :         }
   12803             : 
   12804           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12805             : 
   12806           4 :         status = torture_setup_unix_extensions(cli);
   12807           4 :         if (!NT_STATUS_IS_OK(status)) {
   12808           0 :                 TALLOC_FREE(frame);
   12809           0 :                 return false;
   12810             :         }
   12811             : 
   12812             :         /* Ensure nothing exists. */
   12813           4 :         cli_setatr(cli, fname, 0, 0);
   12814           4 :         cli_posix_unlink(cli, fname);
   12815           4 :         cli_setatr(cli, sname, 0, 0);
   12816           4 :         cli_posix_unlink(cli, sname);
   12817             : 
   12818             :         /* Create a symlink pointing nowhere. */
   12819           4 :         status = cli_posix_symlink(cli, fname, sname);
   12820           4 :         if (!NT_STATUS_IS_OK(status)) {
   12821           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
   12822             :                         sname,
   12823             :                         fname,
   12824             :                         nt_errstr(status));
   12825           0 :                 goto out;
   12826             :         }
   12827             : 
   12828             :         /* Now ensure that a Windows open doesn't hang. */
   12829           4 :         status = cli_ntcreate(cli,
   12830             :                         sname,
   12831             :                         0,
   12832             :                         FILE_READ_DATA|FILE_WRITE_DATA,
   12833             :                         0,
   12834             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   12835             :                         FILE_OPEN_IF,
   12836             :                         0x0,
   12837             :                         0x0,
   12838             :                         &fnum,
   12839             :                         NULL);
   12840             : 
   12841             :         /*
   12842             :          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
   12843             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
   12844             :          * we use O_NOFOLLOW on the server or not.
   12845             :          */
   12846           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
   12847           0 :             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
   12848             :         {
   12849           4 :                 correct = true;
   12850             :         } else {
   12851           0 :                 printf("cli_ntcreate of %s returned %s - should return"
   12852             :                                 " either (%s) or (%s)\n",
   12853             :                         sname,
   12854             :                         nt_errstr(status),
   12855           0 :                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
   12856           0 :                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
   12857           0 :                 goto out;
   12858             :         }
   12859             : 
   12860           4 :         correct = true;
   12861             : 
   12862           4 :   out:
   12863             : 
   12864           4 :         if (fnum != (uint16_t)-1) {
   12865           0 :                 cli_close(cli, fnum);
   12866           0 :                 fnum = (uint16_t)-1;
   12867             :         }
   12868             : 
   12869           4 :         cli_setatr(cli, sname, 0, 0);
   12870           4 :         cli_posix_unlink(cli, sname);
   12871           4 :         cli_setatr(cli, fname, 0, 0);
   12872           4 :         cli_posix_unlink(cli, fname);
   12873             : 
   12874           4 :         if (!torture_close_connection(cli)) {
   12875           0 :                 correct = false;
   12876             :         }
   12877             : 
   12878           4 :         TALLOC_FREE(frame);
   12879           4 :         return correct;
   12880             : }
   12881             : 
   12882          16 : static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
   12883             :                                         const char *name,
   12884             :                                         void *state)
   12885             : {
   12886          16 :         char **mangled_name_return = (char **)state;
   12887          16 :         bool is_mangled = strchr(finfo->name, '~');
   12888             : 
   12889          16 :         if (is_mangled) {
   12890           8 :                 *mangled_name_return = talloc_strdup(NULL, finfo->name);
   12891           8 :                 if (*mangled_name_return == NULL) {
   12892           0 :                         return NT_STATUS_NO_MEMORY;
   12893             :                 }
   12894             :         }
   12895          16 :         return NT_STATUS_OK;
   12896             : }
   12897             : 
   12898           4 : static bool run_smb1_wild_mangle_unlink_test(int dummy)
   12899             : {
   12900           0 :         static struct cli_state *cli_posix = NULL;
   12901           0 :         static struct cli_state *cli = NULL;
   12902           4 :         uint16_t fnum = (uint16_t)-1;
   12903           4 :         bool correct = false;
   12904           4 :         const char *dname = "smb1_wild_mangle_unlink";
   12905           4 :         const char *aname = "smb1_wild_mangle_unlink/a";
   12906           4 :         const char *star_name = "smb1_wild_mangle_unlink/*";
   12907           4 :         char *windows_unlink_name = NULL;
   12908           4 :         char *mangled_name = NULL;
   12909           0 :         NTSTATUS status;
   12910             : 
   12911           4 :         printf("Starting SMB1 wild mangle unlink test\n");
   12912             : 
   12913             :         /* Open a Windows connection. */
   12914           4 :         if (!torture_open_connection(&cli, 0)) {
   12915           0 :                 return false;
   12916             :         }
   12917             : 
   12918           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12919             : 
   12920             :         /* Open a POSIX connection. */
   12921           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   12922           0 :                 goto out;
   12923             :         }
   12924             : 
   12925           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12926             : 
   12927           4 :         status = torture_setup_unix_extensions(cli_posix);
   12928           4 :         if (!NT_STATUS_IS_OK(status)) {
   12929           0 :                 printf("server doesn't support POSIX\n");
   12930           0 :                 goto out;
   12931             :         }
   12932             : 
   12933             :         /* Start fresh. */
   12934           4 :         torture_deltree(cli, dname);
   12935             : 
   12936             :         /*
   12937             :          * Create two files - 'a' and '*'.
   12938             :          * We need POSIX extensions for this as '*'
   12939             :          * is not a valid Windows name.
   12940             :          */
   12941             : 
   12942           4 :         status = cli_mkdir(cli, dname);
   12943           4 :         if (!NT_STATUS_IS_OK(status)) {
   12944           0 :                 printf("cli_mkdir of %s returned %s\n",
   12945             :                         dname,
   12946             :                         nt_errstr(status));
   12947           0 :                 goto out;
   12948             :         }
   12949             : 
   12950           4 :         status = cli_posix_open(cli_posix,
   12951             :                                 aname,
   12952             :                                 O_RDWR|O_CREAT|O_EXCL,
   12953             :                                 0660,
   12954             :                                 &fnum);
   12955           4 :         if (!NT_STATUS_IS_OK(status)) {
   12956           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12957             :                         aname,
   12958             :                         nt_errstr(status));
   12959           0 :                 goto out;
   12960             :         }
   12961           4 :         status = cli_close(cli_posix, fnum);
   12962           4 :         if (!NT_STATUS_IS_OK(status)) {
   12963           0 :                 goto out;
   12964             :         }
   12965           4 :         status = cli_posix_open(cli_posix,
   12966             :                                 star_name,
   12967             :                                 O_RDWR|O_CREAT|O_EXCL,
   12968             :                                 0660,
   12969             :                                 &fnum);
   12970           4 :         if (!NT_STATUS_IS_OK(status)) {
   12971           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12972             :                         star_name,
   12973             :                         nt_errstr(status));
   12974           0 :                 goto out;
   12975             :         }
   12976           4 :         status = cli_close(cli_posix, fnum);
   12977           4 :         if (!NT_STATUS_IS_OK(status)) {
   12978           0 :                 goto out;
   12979             :         }
   12980             : 
   12981           4 :         status = cli_list(cli,
   12982             :                         star_name,
   12983             :                         0,
   12984             :                         smb1_wild_mangle_list_fn,
   12985             :                         &mangled_name);
   12986           4 :         if (!NT_STATUS_IS_OK(status)) {
   12987           0 :                 printf("cli_list of %s returned %s\n",
   12988             :                         star_name,
   12989             :                         nt_errstr(status));
   12990           0 :                 goto out;
   12991             :         }
   12992             : 
   12993           4 :         if (mangled_name == NULL) {
   12994           0 :                 goto out;
   12995             :         }
   12996             : 
   12997           4 :         printf("mangled_name = %s\n",
   12998             :                 mangled_name);
   12999             : 
   13000             :         /*
   13001             :          * Try a Windows unlink with the mangled name.
   13002             :          * This should *NOT* unlink the 'a' name.
   13003             :          */
   13004             : 
   13005           4 :         windows_unlink_name = talloc_asprintf(cli_posix,
   13006             :                                         "%s\\%s",
   13007             :                                         dname,
   13008             :                                         mangled_name);
   13009             : 
   13010           4 :         status = cli_unlink(cli, windows_unlink_name, 0);
   13011           4 :         if (!NT_STATUS_IS_OK(status)) {
   13012           0 :                 printf("cli_unlink of %s returned %s\n",
   13013             :                         windows_unlink_name,
   13014             :                         nt_errstr(status));
   13015           0 :                 goto out;
   13016             :         }
   13017             : 
   13018             :         /* Does 'a' still exist ? */
   13019           4 :         status = cli_posix_open(cli_posix,
   13020             :                                 aname,
   13021             :                                 O_RDONLY,
   13022             :                                 0,
   13023             :                                 &fnum);
   13024           4 :         if (!NT_STATUS_IS_OK(status)) {
   13025           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13026             :                         aname,
   13027             :                         nt_errstr(status));
   13028           0 :                 goto out;
   13029             :         }
   13030             : 
   13031           4 :         status = cli_close(cli_posix, fnum);
   13032           4 :         if (!NT_STATUS_IS_OK(status)) {
   13033           0 :                 goto out;
   13034             :         }
   13035             : 
   13036           4 :         correct = true;
   13037             : 
   13038           4 :   out:
   13039             : 
   13040           4 :         TALLOC_FREE(windows_unlink_name);
   13041           4 :         TALLOC_FREE(mangled_name);
   13042             : 
   13043           4 :         if (cli != NULL) {
   13044           4 :                 torture_deltree(cli, dname);
   13045           4 :                 torture_close_connection(cli);
   13046             :         }
   13047             : 
   13048           4 :         if (cli_posix != NULL) {
   13049           4 :                 torture_close_connection(cli_posix);
   13050             :         }
   13051             : 
   13052           4 :         return correct;
   13053             : }
   13054             : 
   13055           4 : static bool run_smb1_wild_mangle_rename_test(int dummy)
   13056             : {
   13057           0 :         static struct cli_state *cli_posix = NULL;
   13058           0 :         static struct cli_state *cli = NULL;
   13059           4 :         uint16_t fnum = (uint16_t)-1;
   13060           4 :         bool correct = false;
   13061           4 :         const char *dname = "smb1_wild_mangle_rename";
   13062           4 :         const char *fooname = "smb1_wild_mangle_rename/foo";
   13063           4 :         const char *foostar_name = "smb1_wild_mangle_rename/fo*";
   13064           4 :         const char *wild_name = "smb1_wild_mangle_rename/*";
   13065           4 :         char *windows_rename_src = NULL;
   13066           4 :         const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
   13067           4 :         char *mangled_name = NULL;
   13068           0 :         NTSTATUS status;
   13069             : 
   13070           4 :         printf("Starting SMB1 wild mangle rename test\n");
   13071             : 
   13072           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   13073           0 :                 return false;
   13074             :         }
   13075             : 
   13076           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   13077             : 
   13078           4 :         status = torture_setup_unix_extensions(cli_posix);
   13079           4 :         if (!NT_STATUS_IS_OK(status)) {
   13080           0 :                 printf("server doesn't support POSIX\n");
   13081           0 :                 return false;
   13082             :         }
   13083             : 
   13084             :         /* Open a Windows connection. */
   13085           4 :         if (!torture_open_connection(&cli, 0)) {
   13086           0 :                 goto out;
   13087             :         }
   13088             : 
   13089           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   13090             : 
   13091             :         /* Ensure we start from fresh. */
   13092           4 :         torture_deltree(cli, dname);
   13093             : 
   13094             :         /*
   13095             :          * Create two files - 'foo' and 'fo*'.
   13096             :          * We need POSIX extensions for this as 'fo*'
   13097             :          * is not a valid Windows name.
   13098             :          */
   13099             : 
   13100           4 :         status = cli_posix_mkdir(cli_posix, dname, 0770);
   13101           4 :         if (!NT_STATUS_IS_OK(status)) {
   13102           0 :                 printf("cli_posix_mkdir of %s returned %s\n",
   13103             :                         dname,
   13104             :                         nt_errstr(status));
   13105           0 :                 goto out;
   13106             :         }
   13107             : 
   13108           4 :         status = cli_posix_open(cli_posix,
   13109             :                                 fooname,
   13110             :                                 O_RDWR|O_CREAT|O_EXCL,
   13111             :                                 0660,
   13112             :                                 &fnum);
   13113           4 :         if (!NT_STATUS_IS_OK(status)) {
   13114           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13115             :                         fooname,
   13116             :                         nt_errstr(status));
   13117           0 :                 goto out;
   13118             :         }
   13119           4 :         status = cli_close(cli_posix, fnum);
   13120           4 :         if (!NT_STATUS_IS_OK(status)) {
   13121           0 :                 goto out;
   13122             :         }
   13123           4 :         status = cli_posix_open(cli_posix,
   13124             :                                 foostar_name,
   13125             :                                 O_RDWR|O_CREAT|O_EXCL,
   13126             :                                 0660,
   13127             :                                 &fnum);
   13128           4 :         if (!NT_STATUS_IS_OK(status)) {
   13129           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13130             :                         foostar_name,
   13131             :                         nt_errstr(status));
   13132           0 :                 goto out;
   13133             :         }
   13134           4 :         status = cli_close(cli_posix, fnum);
   13135           4 :         if (!NT_STATUS_IS_OK(status)) {
   13136           0 :                 goto out;
   13137             :         }
   13138             : 
   13139             :         /*
   13140             :          * Get the mangled name. We can re-use the
   13141             :          * previous smb1_wild_mangle_list_fn for this.
   13142             :          */
   13143             : 
   13144           4 :         status = cli_list(cli,
   13145             :                         wild_name,
   13146             :                         0,
   13147             :                         smb1_wild_mangle_list_fn,
   13148             :                         &mangled_name);
   13149           4 :         if (!NT_STATUS_IS_OK(status)) {
   13150           0 :                 printf("cli_list of %s returned %s\n",
   13151             :                         wild_name,
   13152             :                         nt_errstr(status));
   13153           0 :                 goto out;
   13154             :         }
   13155             : 
   13156           4 :         if (mangled_name == NULL) {
   13157           0 :                 goto out;
   13158             :         }
   13159             : 
   13160           4 :         printf("mangled_name = %s\n",
   13161             :                 mangled_name);
   13162             : 
   13163             :         /*
   13164             :          * Try a Windows rename with the mangled name.
   13165             :          * This should *NOT* rename the 'foo' name.
   13166             :          */
   13167             : 
   13168           4 :         windows_rename_src = talloc_asprintf(cli_posix,
   13169             :                                         "%s\\%s",
   13170             :                                         dname,
   13171             :                                         mangled_name);
   13172             : 
   13173           4 :         status = cli_rename(cli,
   13174             :                         windows_rename_src,
   13175             :                         windows_rename_dst,
   13176             :                         false);
   13177           4 :         if (!NT_STATUS_IS_OK(status)) {
   13178           0 :                 printf("cli_rename of %s -> %s returned %s\n",
   13179             :                         windows_rename_src,
   13180             :                         windows_rename_dst,
   13181             :                         nt_errstr(status));
   13182           0 :                 goto out;
   13183             :         }
   13184             : 
   13185             :         /* Does 'foo' still exist ? */
   13186           4 :         status = cli_posix_open(cli_posix,
   13187             :                                 fooname,
   13188             :                                 O_RDONLY,
   13189             :                                 0,
   13190             :                                 &fnum);
   13191           4 :         if (!NT_STATUS_IS_OK(status)) {
   13192           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13193             :                         fooname,
   13194             :                         nt_errstr(status));
   13195           0 :                 goto out;
   13196             :         }
   13197             : 
   13198           4 :         status = cli_close(cli_posix, fnum);
   13199           4 :         if (!NT_STATUS_IS_OK(status)) {
   13200           0 :                 goto out;
   13201             :         }
   13202             : 
   13203           4 :         correct = true;
   13204             : 
   13205           4 :   out:
   13206             : 
   13207           4 :         TALLOC_FREE(mangled_name);
   13208           4 :         TALLOC_FREE(windows_rename_src);
   13209             : 
   13210           4 :         if (cli != NULL) {
   13211           4 :                 torture_deltree(cli, dname);
   13212           4 :                 torture_close_connection(cli);
   13213             :         }
   13214             : 
   13215           4 :         torture_close_connection(cli_posix);
   13216             : 
   13217           4 :         return correct;
   13218             : }
   13219             : 
   13220             : /*
   13221             :  * Only testing minimal time strings, as the others
   13222             :  * need (locale-dependent) guessing at what strftime does and
   13223             :  * even may differ in builds.
   13224             :  */
   13225           1 : static bool timesubst_test(void)
   13226             : {
   13227           1 :         TALLOC_CTX *ctx = NULL;
   13228             :         /* Sa 23. Dez 04:33:20 CET 2017 */
   13229           1 :         const struct timeval tv = { 1514000000, 123 };
   13230           1 :         const char* expect_minimal = "20171223_033320";
   13231           1 :         const char* expect_minus   = "20171223_033320_000123";
   13232           1 :         char *s;
   13233           1 :         char *env_tz, *orig_tz = NULL;
   13234           1 :         bool result = true;
   13235             : 
   13236           1 :         ctx = talloc_new(NULL);
   13237             : 
   13238           1 :         env_tz = getenv("TZ");
   13239           1 :         if(env_tz) {
   13240           1 :                 orig_tz = talloc_strdup(ctx, env_tz);
   13241             :         }
   13242           1 :         setenv("TZ", "UTC", 1);
   13243             : 
   13244           1 :         s = minimal_timeval_string(ctx, &tv, false);
   13245             : 
   13246           1 :         if(!s || strcmp(s, expect_minimal)) {
   13247           0 :                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
   13248             :                        "[%s]\n", s ? s : "<nil>", expect_minimal);
   13249           0 :                 result = false;
   13250             :         }
   13251           1 :         TALLOC_FREE(s);
   13252           1 :         s = minimal_timeval_string(ctx, &tv, true);
   13253           1 :         if(!s || strcmp(s, expect_minus)) {
   13254           0 :                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
   13255             :                        "[%s]\n", s ? s : "<nil>", expect_minus);
   13256           0 :                 result = false;
   13257             :         }
   13258           1 :         TALLOC_FREE(s);
   13259             : 
   13260           1 :         if(orig_tz) {
   13261           1 :                 setenv("TZ", orig_tz, 1);
   13262             :         }
   13263             : 
   13264           1 :         TALLOC_FREE(ctx);
   13265           1 :         return result;
   13266             : }
   13267             : 
   13268           1 : static bool run_local_substitute(int dummy)
   13269             : {
   13270           1 :         bool ok = true;
   13271             : 
   13272           1 :         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
   13273           1 :         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
   13274           1 :         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
   13275           1 :         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
   13276           1 :         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
   13277           1 :         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
   13278           1 :         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
   13279           1 :         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
   13280           1 :         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
   13281             :         /* Substitution depends on current time, so better test the underlying
   13282             :            formatting function. At least covers %t. */
   13283           1 :         ok &= timesubst_test();
   13284             : 
   13285             :         /* Different captialization rules in sub_basic... */
   13286             : 
   13287           1 :         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
   13288           1 :                        "blaDOM") == 0);
   13289             : 
   13290           1 :         return ok;
   13291             : }
   13292             : 
   13293           1 : static bool run_local_base64(int dummy)
   13294             : {
   13295           1 :         int i;
   13296           1 :         bool ret = true;
   13297             : 
   13298        2000 :         for (i=1; i<2000; i++) {
   13299        1999 :                 DATA_BLOB blob1, blob2;
   13300        1999 :                 char *b64;
   13301             : 
   13302        1999 :                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
   13303        1999 :                 blob1.length = i;
   13304        1999 :                 generate_random_buffer(blob1.data, blob1.length);
   13305             : 
   13306        1999 :                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
   13307        1999 :                 if (b64 == NULL) {
   13308           0 :                         d_fprintf(stderr, "base64_encode_data_blob failed "
   13309             :                                   "for %d bytes\n", i);
   13310           0 :                         ret = false;
   13311             :                 }
   13312        1999 :                 blob2 = base64_decode_data_blob(b64);
   13313        1999 :                 TALLOC_FREE(b64);
   13314             : 
   13315        1999 :                 if (data_blob_cmp(&blob1, &blob2)) {
   13316           0 :                         d_fprintf(stderr, "data_blob_cmp failed for %d "
   13317             :                                   "bytes\n", i);
   13318           0 :                         ret = false;
   13319             :                 }
   13320        1999 :                 TALLOC_FREE(blob1.data);
   13321        1999 :                 data_blob_free(&blob2);
   13322             :         }
   13323           1 :         return ret;
   13324             : }
   13325             : 
   13326     1000000 : static void parse_fn(const struct gencache_timeout *t,
   13327             :                      DATA_BLOB blob,
   13328             :                      void *private_data)
   13329             : {
   13330     1000000 :         return;
   13331             : }
   13332             : 
   13333           1 : static bool run_local_gencache(int dummy)
   13334             : {
   13335           1 :         char *val;
   13336           1 :         time_t tm;
   13337           1 :         DATA_BLOB blob;
   13338           1 :         char v;
   13339           1 :         struct memcache *mem;
   13340           1 :         int i;
   13341             : 
   13342           1 :         mem = memcache_init(NULL, 0);
   13343           1 :         if (mem == NULL) {
   13344           0 :                 d_printf("%s: memcache_init failed\n", __location__);
   13345           0 :                 return false;
   13346             :         }
   13347           1 :         memcache_set_global(mem);
   13348             : 
   13349           1 :         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
   13350           0 :                 d_printf("%s: gencache_set() failed\n", __location__);
   13351           0 :                 return False;
   13352             :         }
   13353             : 
   13354           1 :         if (!gencache_get("foo", NULL, NULL, NULL)) {
   13355           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13356           0 :                 return False;
   13357             :         }
   13358             : 
   13359     1000001 :         for (i=0; i<1000000; i++) {
   13360     1000000 :                 gencache_parse("foo", parse_fn, NULL);
   13361             :         }
   13362             : 
   13363           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13364           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13365           0 :                 return False;
   13366             :         }
   13367           1 :         TALLOC_FREE(val);
   13368             : 
   13369           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13370           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13371           0 :                 return False;
   13372             :         }
   13373             : 
   13374           1 :         if (strcmp(val, "bar") != 0) {
   13375           0 :                 d_printf("%s: gencache_get() returned %s, expected %s\n",
   13376             :                          __location__, val, "bar");
   13377           0 :                 TALLOC_FREE(val);
   13378           0 :                 return False;
   13379             :         }
   13380             : 
   13381           1 :         TALLOC_FREE(val);
   13382             : 
   13383           1 :         if (!gencache_del("foo")) {
   13384           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13385           0 :                 return False;
   13386             :         }
   13387           1 :         if (gencache_del("foo")) {
   13388           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13389             :                          __location__);
   13390           0 :                 return False;
   13391             :         }
   13392             : 
   13393           1 :         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
   13394           0 :                 d_printf("%s: gencache_get() on deleted entry "
   13395             :                          "succeeded\n", __location__);
   13396           0 :                 return False;
   13397             :         }
   13398             : 
   13399           1 :         blob = data_blob_string_const_null("bar");
   13400           1 :         tm = time(NULL) + 60;
   13401             : 
   13402           1 :         if (!gencache_set_data_blob("foo", blob, tm)) {
   13403           0 :                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
   13404           0 :                 return False;
   13405             :         }
   13406             : 
   13407           1 :         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13408           0 :                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
   13409           0 :                 return False;
   13410             :         }
   13411             : 
   13412           1 :         if (strcmp((const char *)blob.data, "bar") != 0) {
   13413           0 :                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
   13414           0 :                          __location__, (const char *)blob.data, "bar");
   13415           0 :                 data_blob_free(&blob);
   13416           0 :                 return False;
   13417             :         }
   13418             : 
   13419           1 :         data_blob_free(&blob);
   13420             : 
   13421           1 :         if (!gencache_del("foo")) {
   13422           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13423           0 :                 return False;
   13424             :         }
   13425           1 :         if (gencache_del("foo")) {
   13426           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13427             :                          __location__);
   13428           0 :                 return False;
   13429             :         }
   13430             : 
   13431           1 :         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13432           0 :                 d_printf("%s: gencache_get_data_blob() on deleted entry "
   13433             :                          "succeeded\n", __location__);
   13434           0 :                 return False;
   13435             :         }
   13436             : 
   13437           1 :         v = 1;
   13438           1 :         blob.data = (uint8_t *)&v;
   13439           1 :         blob.length = sizeof(v);
   13440             : 
   13441           1 :         if (!gencache_set_data_blob("blob", blob, tm)) {
   13442           0 :                 d_printf("%s: gencache_set_data_blob() failed\n",
   13443             :                          __location__);
   13444           0 :                 return false;
   13445             :         }
   13446           1 :         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
   13447           0 :                 d_printf("%s: gencache_get succeeded\n", __location__);
   13448           0 :                 return false;
   13449             :         }
   13450             : 
   13451           0 :         return True;
   13452             : }
   13453             : 
   13454           1 : static bool rbt_testflags(struct db_context *db, const char *key,
   13455             :                           const char *value)
   13456             : {
   13457           1 :         bool ret = false;
   13458           1 :         NTSTATUS status;
   13459           1 :         struct db_record *rec;
   13460             : 
   13461           1 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13462           1 :         if (rec == NULL) {
   13463           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13464           0 :                 goto done;
   13465             :         }
   13466             : 
   13467           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13468           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   13469           0 :                 d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
   13470             :                           nt_errstr(status));
   13471           0 :                 goto done;
   13472             :         }
   13473             : 
   13474           1 :         status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
   13475             :                                      TDB_INSERT);
   13476           1 :         if (!NT_STATUS_IS_OK(status)) {
   13477           0 :                 d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
   13478             :                           nt_errstr(status));
   13479           0 :                 goto done;
   13480             :         }
   13481             : 
   13482           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
   13483           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
   13484           0 :                 d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
   13485             :                           nt_errstr(status));
   13486           0 :                 goto done;
   13487             :         }
   13488             : 
   13489           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13490           1 :         if (!NT_STATUS_IS_OK(status)) {
   13491           0 :                 d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
   13492             :                           nt_errstr(status));
   13493           0 :                 goto done;
   13494             :         }
   13495             : 
   13496           0 :         ret = true;
   13497           1 : done:
   13498           1 :         TALLOC_FREE(rec);
   13499           1 :         return ret;
   13500             : }
   13501             : 
   13502        1998 : static bool rbt_testval(struct db_context *db, const char *key,
   13503             :                         const char *value)
   13504             : {
   13505        1998 :         struct db_record *rec;
   13506        1998 :         TDB_DATA data = string_tdb_data(value);
   13507        1998 :         bool ret = false;
   13508        1998 :         NTSTATUS status;
   13509        1998 :         TDB_DATA dbvalue;
   13510             : 
   13511        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13512        1998 :         if (rec == NULL) {
   13513           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13514           0 :                 goto done;
   13515             :         }
   13516        1998 :         status = dbwrap_record_store(rec, data, 0);
   13517        1998 :         if (!NT_STATUS_IS_OK(status)) {
   13518           0 :                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
   13519           0 :                 goto done;
   13520             :         }
   13521        1998 :         TALLOC_FREE(rec);
   13522             : 
   13523        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13524        1998 :         if (rec == NULL) {
   13525           0 :                 d_fprintf(stderr, "second fetch_locked failed\n");
   13526           0 :                 goto done;
   13527             :         }
   13528             : 
   13529        1998 :         dbvalue = dbwrap_record_get_value(rec);
   13530        1998 :         if ((dbvalue.dsize != data.dsize)
   13531        1998 :             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
   13532           0 :                 d_fprintf(stderr, "Got wrong data back\n");
   13533           0 :                 goto done;
   13534             :         }
   13535             : 
   13536           0 :         ret = true;
   13537        1998 :  done:
   13538        1998 :         TALLOC_FREE(rec);
   13539        1998 :         return ret;
   13540             : }
   13541             : 
   13542        1000 : static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
   13543             : {
   13544        1000 :         int *count2 = (int *)private_data;
   13545        1000 :         (*count2)++;
   13546        1000 :         return 0;
   13547             : }
   13548             : 
   13549        1000 : static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
   13550             : {
   13551        1000 :         int *count2 = (int *)private_data;
   13552        1000 :         (*count2)++;
   13553        1000 :         dbwrap_record_delete(rec);
   13554        1000 :         return 0;
   13555             : }
   13556             : 
   13557           1 : static bool run_local_rbtree(int dummy)
   13558             : {
   13559           1 :         struct db_context *db;
   13560           1 :         bool ret = false;
   13561           1 :         int i;
   13562           1 :         NTSTATUS status;
   13563           1 :         int count = 0;
   13564           1 :         int count2 = 0;
   13565             : 
   13566           1 :         db = db_open_rbt(NULL);
   13567             : 
   13568           1 :         if (db == NULL) {
   13569           0 :                 d_fprintf(stderr, "db_open_rbt failed\n");
   13570           0 :                 return false;
   13571             :         }
   13572             : 
   13573           1 :         if (!rbt_testflags(db, "firstkey", "firstval")) {
   13574           0 :                 goto done;
   13575             :         }
   13576             : 
   13577        1000 :         for (i = 0; i < 999; i++) {
   13578         999 :                 char key[sizeof("key-9223372036854775807")];
   13579         999 :                 char value[sizeof("value-9223372036854775807")];
   13580             : 
   13581         999 :                 snprintf(key, sizeof(key), "key%ld", random());
   13582         999 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13583             : 
   13584         999 :                 if (!rbt_testval(db, key, value)) {
   13585           0 :                         goto done;
   13586             :                 }
   13587             : 
   13588         999 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13589             : 
   13590         999 :                 if (!rbt_testval(db, key, value)) {
   13591           0 :                         goto done;
   13592             :                 }
   13593             :         }
   13594             : 
   13595           1 :         ret = true;
   13596           1 :         count = 0; count2 = 0;
   13597           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13598             :                                       &count2, &count);
   13599           1 :         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13600           1 :         if ((count != count2) || (count != 1000)) {
   13601           0 :                 ret = false;
   13602             :         }
   13603           1 :         count = 0; count2 = 0;
   13604           1 :         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
   13605             :                                  &count2, &count);
   13606           1 :         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13607           1 :         if ((count != count2) || (count != 1000)) {
   13608           0 :                 ret = false;
   13609             :         }
   13610           1 :         count = 0; count2 = 0;
   13611           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13612             :                                       &count2, &count);
   13613           1 :         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13614           1 :         if ((count != count2) || (count != 0)) {
   13615           0 :                 ret = false;
   13616             :         }
   13617             : 
   13618           1 :  done:
   13619           1 :         TALLOC_FREE(db);
   13620           1 :         return ret;
   13621             : }
   13622             : 
   13623             : 
   13624             : /*
   13625             :   local test for character set functions
   13626             : 
   13627             :   This is a very simple test for the functionality in convert_string_error()
   13628             :  */
   13629           1 : static bool run_local_convert_string(int dummy)
   13630             : {
   13631           1 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   13632           1 :         const char *test_strings[2] = { "March", "M\303\244rz" };
   13633           1 :         char dst[7];
   13634           1 :         int i;
   13635             : 
   13636           3 :         for (i=0; i<2; i++) {
   13637           2 :                 const char *str = test_strings[i];
   13638           2 :                 int len = strlen(str);
   13639           2 :                 size_t converted_size;
   13640           2 :                 bool ret;
   13641             : 
   13642           2 :                 memset(dst, 'X', sizeof(dst));
   13643             : 
   13644             :                 /* first try with real source length */
   13645           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13646             :                                            str, len,
   13647             :                                            dst, sizeof(dst),
   13648             :                                            &converted_size);
   13649           2 :                 if (ret != true) {
   13650           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13651           0 :                         goto failed;
   13652             :                 }
   13653             : 
   13654           2 :                 if (converted_size != len) {
   13655           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13656             :                                   str, len, (int)converted_size);
   13657           0 :                         goto failed;
   13658             :                 }
   13659             : 
   13660           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13661           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13662           0 :                         goto failed;
   13663             :                 }
   13664             : 
   13665           2 :                 if (strlen(str) != converted_size) {
   13666           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13667           0 :                                   (int)strlen(str), (int)converted_size);
   13668           0 :                         goto failed;
   13669             :                 }
   13670             : 
   13671           2 :                 if (dst[converted_size] != 'X') {
   13672           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13673           0 :                         goto failed;
   13674             :                 }
   13675             : 
   13676             :                 /* now with srclen==-1, this causes the nul to be
   13677             :                  * converted too */
   13678           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13679             :                                            str, -1,
   13680             :                                            dst, sizeof(dst),
   13681             :                                            &converted_size);
   13682           2 :                 if (ret != true) {
   13683           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13684           0 :                         goto failed;
   13685             :                 }
   13686             : 
   13687           2 :                 if (converted_size != len+1) {
   13688           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13689             :                                   str, len, (int)converted_size);
   13690           0 :                         goto failed;
   13691             :                 }
   13692             : 
   13693           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13694           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13695           0 :                         goto failed;
   13696             :                 }
   13697             : 
   13698           2 :                 if (len+1 != converted_size) {
   13699           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13700             :                                   len+1, (int)converted_size);
   13701           0 :                         goto failed;
   13702             :                 }
   13703             : 
   13704           2 :                 if (dst[converted_size] != 'X') {
   13705           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13706           0 :                         goto failed;
   13707             :                 }
   13708             : 
   13709             :         }
   13710             : 
   13711             : 
   13712           1 :         TALLOC_FREE(tmp_ctx);
   13713           0 :         return true;
   13714           0 : failed:
   13715           0 :         TALLOC_FREE(tmp_ctx);
   13716           0 :         return false;
   13717             : }
   13718             : 
   13719           1 : static bool run_local_string_to_sid(int dummy) {
   13720           1 :         struct dom_sid sid;
   13721             : 
   13722           1 :         if (string_to_sid(&sid, "S--1-5-32-545")) {
   13723           0 :                 printf("allowing S--1-5-32-545\n");
   13724           0 :                 return false;
   13725             :         }
   13726           1 :         if (string_to_sid(&sid, "S-1-5-32-+545")) {
   13727           0 :                 printf("allowing S-1-5-32-+545\n");
   13728           0 :                 return false;
   13729             :         }
   13730           1 :         if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
   13731           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");
   13732           0 :                 return false;
   13733             :         }
   13734           1 :         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
   13735           0 :                 printf("allowing S-1-5-32-545-abc\n");
   13736           0 :                 return false;
   13737             :         }
   13738           1 :         if (string_to_sid(&sid, "S-300-5-32-545")) {
   13739           0 :                 printf("allowing S-300-5-32-545\n");
   13740           0 :                 return false;
   13741             :         }
   13742           1 :         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
   13743           0 :                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
   13744           0 :                 return false;
   13745             :         }
   13746           1 :         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
   13747           0 :                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
   13748           0 :                 return false;
   13749             :         }
   13750           1 :         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
   13751           0 :                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
   13752           0 :                 return false;
   13753             :         }
   13754           1 :         if (!string_to_sid(&sid, "S-1-5-32-545")) {
   13755           0 :                 printf("could not parse S-1-5-32-545\n");
   13756           0 :                 return false;
   13757             :         }
   13758           1 :         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
   13759           0 :                 struct dom_sid_buf buf;
   13760           0 :                 printf("mis-parsed S-1-5-32-545 as %s\n",
   13761             :                        dom_sid_str_buf(&sid, &buf));
   13762           0 :                 return false;
   13763             :         }
   13764           0 :         return true;
   13765             : }
   13766             : 
   13767           3 : static bool sid_to_string_test(const char *expected) {
   13768           3 :         char *str;
   13769           3 :         bool res = true;
   13770           3 :         struct dom_sid sid;
   13771             : 
   13772           3 :         if (!string_to_sid(&sid, expected)) {
   13773           0 :                 printf("could not parse %s\n", expected);
   13774           0 :                 return false;
   13775             :         }
   13776             : 
   13777           3 :         str = dom_sid_string(NULL, &sid);
   13778           3 :         if (strcmp(str, expected)) {
   13779           0 :                 printf("Comparison failed (%s != %s)\n", str, expected);
   13780           0 :                 res = false;
   13781             :         }
   13782           3 :         TALLOC_FREE(str);
   13783           3 :         return res;
   13784             : }
   13785             : 
   13786           1 : static bool run_local_sid_to_string(int dummy) {
   13787           1 :         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
   13788           0 :                 return false;
   13789           1 :         if (!sid_to_string_test("S-1-545"))
   13790           0 :                 return false;
   13791           1 :         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
   13792           0 :                 return false;
   13793           0 :         return true;
   13794             : }
   13795             : 
   13796           1 : static bool run_local_binary_to_sid(int dummy) {
   13797           1 :         ssize_t ret;
   13798           1 :         struct dom_sid *sid = talloc(NULL, struct dom_sid);
   13799           1 :         static const uint8_t good_binary_sid[] = {
   13800             :                 0x1, /* revision number */
   13801             :                 15, /* num auths */
   13802             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13803             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13804             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13805             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13806             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13807             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13808             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13809             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13810             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13811             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13812             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13813             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13814             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13815             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13816             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13817             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13818             :         };
   13819             : 
   13820           1 :         static const uint8_t long_binary_sid[] = {
   13821             :                 0x1, /* revision number */
   13822             :                 15, /* num auths */
   13823             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13824             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13825             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13826             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13827             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13828             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13829             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13830             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13831             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13832             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13833             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13834             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13835             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13836             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13837             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13838             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13839             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13840             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13841             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13842             :         };
   13843             : 
   13844           1 :         static const uint8_t long_binary_sid2[] = {
   13845             :                 0x1, /* revision number */
   13846             :                 32, /* num auths */
   13847             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13848             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13849             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13850             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13851             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13852             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13853             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13854             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13855             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13856             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13857             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13858             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13859             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13860             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13861             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13862             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13863             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13864             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13865             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13866             :                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
   13867             :                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
   13868             :                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
   13869             :                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
   13870             :                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
   13871             :                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
   13872             :                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
   13873             :                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
   13874             :                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
   13875             :                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
   13876             :                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
   13877             :                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
   13878             :                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
   13879             :                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
   13880             :         };
   13881             : 
   13882           1 :         ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
   13883           1 :         if (ret == -1) {
   13884           0 :                 return false;
   13885             :         }
   13886           1 :         ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
   13887           1 :         if (ret != -1) {
   13888           0 :                 return false;
   13889             :         }
   13890           1 :         ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
   13891           1 :         if (ret != -1) {
   13892           0 :                 return false;
   13893             :         }
   13894           0 :         return true;
   13895             : }
   13896             : 
   13897             : /* Split a path name into filename and stream name components. Canonicalise
   13898             :  * such that an implicit $DATA token is always explicit.
   13899             :  *
   13900             :  * The "specification" of this function can be found in the
   13901             :  * run_local_stream_name() function in torture.c, I've tried those
   13902             :  * combinations against a W2k3 server.
   13903             :  */
   13904             : 
   13905           8 : static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
   13906             :                                        char **pbase, char **pstream)
   13907             : {
   13908           8 :         char *base = NULL;
   13909           8 :         char *stream = NULL;
   13910           8 :         char *sname; /* stream name */
   13911           8 :         const char *stype; /* stream type */
   13912             : 
   13913           8 :         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
   13914             : 
   13915           8 :         sname = strchr_m(fname, ':');
   13916             : 
   13917           8 :         if (sname == NULL) {
   13918           1 :                 if (pbase != NULL) {
   13919           1 :                         base = talloc_strdup(mem_ctx, fname);
   13920           1 :                         NT_STATUS_HAVE_NO_MEMORY(base);
   13921             :                 }
   13922           1 :                 goto done;
   13923             :         }
   13924             : 
   13925           7 :         if (pbase != NULL) {
   13926           7 :                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
   13927           7 :                 NT_STATUS_HAVE_NO_MEMORY(base);
   13928             :         }
   13929             : 
   13930           7 :         sname += 1;
   13931             : 
   13932           7 :         stype = strchr_m(sname, ':');
   13933             : 
   13934           7 :         if (stype == NULL) {
   13935           2 :                 sname = talloc_strdup(mem_ctx, sname);
   13936           2 :                 stype = "$DATA";
   13937             :         }
   13938             :         else {
   13939           5 :                 if (strcasecmp_m(stype, ":$DATA") != 0) {
   13940             :                         /*
   13941             :                          * If there is an explicit stream type, so far we only
   13942             :                          * allow $DATA. Is there anything else allowed? -- vl
   13943             :                          */
   13944           3 :                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
   13945           3 :                         TALLOC_FREE(base);
   13946           3 :                         return NT_STATUS_OBJECT_NAME_INVALID;
   13947             :                 }
   13948           2 :                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
   13949           2 :                 stype += 1;
   13950             :         }
   13951             : 
   13952           4 :         if (sname == NULL) {
   13953           0 :                 TALLOC_FREE(base);
   13954           0 :                 return NT_STATUS_NO_MEMORY;
   13955             :         }
   13956             : 
   13957           4 :         if (sname[0] == '\0') {
   13958             :                 /*
   13959             :                  * no stream name, so no stream
   13960             :                  */
   13961           1 :                 goto done;
   13962             :         }
   13963             : 
   13964           3 :         if (pstream != NULL) {
   13965           3 :                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
   13966           3 :                 if (stream == NULL) {
   13967           0 :                         TALLOC_FREE(sname);
   13968           0 :                         TALLOC_FREE(base);
   13969           0 :                         return NT_STATUS_NO_MEMORY;
   13970             :                 }
   13971             :                 /*
   13972             :                  * upper-case the type field
   13973             :                  */
   13974           3 :                 (void)strupper_m(strchr_m(stream, ':')+1);
   13975             :         }
   13976             : 
   13977           0 :  done:
   13978           5 :         if (pbase != NULL) {
   13979           5 :                 *pbase = base;
   13980             :         }
   13981           5 :         if (pstream != NULL) {
   13982           5 :                 *pstream = stream;
   13983             :         }
   13984           5 :         return NT_STATUS_OK;
   13985             : }
   13986             : 
   13987           8 : static bool test_stream_name(const char *fname, const char *expected_base,
   13988             :                              const char *expected_stream,
   13989             :                              NTSTATUS expected_status)
   13990             : {
   13991           8 :         NTSTATUS status;
   13992           8 :         char *base = NULL;
   13993           8 :         char *stream = NULL;
   13994             : 
   13995           8 :         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
   13996           8 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   13997           0 :                 goto error;
   13998             :         }
   13999             : 
   14000           8 :         if (!NT_STATUS_IS_OK(status)) {
   14001           0 :                 return true;
   14002             :         }
   14003             : 
   14004           5 :         if (base == NULL) goto error;
   14005             : 
   14006           5 :         if (strcmp(expected_base, base) != 0) goto error;
   14007             : 
   14008           5 :         if ((expected_stream != NULL) && (stream == NULL)) goto error;
   14009           5 :         if ((expected_stream == NULL) && (stream != NULL)) goto error;
   14010             : 
   14011           5 :         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
   14012           0 :                 goto error;
   14013             : 
   14014           5 :         TALLOC_FREE(base);
   14015           5 :         TALLOC_FREE(stream);
   14016           0 :         return true;
   14017             : 
   14018           0 :  error:
   14019           0 :         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
   14020             :                   fname, expected_base ? expected_base : "<NULL>",
   14021             :                   expected_stream ? expected_stream : "<NULL>",
   14022             :                   nt_errstr(expected_status));
   14023           0 :         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
   14024           0 :                   base ? base : "<NULL>", stream ? stream : "<NULL>",
   14025             :                   nt_errstr(status));
   14026           0 :         TALLOC_FREE(base);
   14027           0 :         TALLOC_FREE(stream);
   14028           0 :         return false;
   14029             : }
   14030             : 
   14031           1 : static bool run_local_stream_name(int dummy)
   14032             : {
   14033           1 :         bool ret = true;
   14034             : 
   14035           2 :         ret &= test_stream_name(
   14036           1 :                 "bla", "bla", NULL, NT_STATUS_OK);
   14037           2 :         ret &= test_stream_name(
   14038           1 :                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
   14039           2 :         ret &= test_stream_name(
   14040           1 :                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14041           2 :         ret &= test_stream_name(
   14042           1 :                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14043           2 :         ret &= test_stream_name(
   14044           1 :                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14045           2 :         ret &= test_stream_name(
   14046           1 :                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
   14047           2 :         ret &= test_stream_name(
   14048           1 :                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
   14049           2 :         ret &= test_stream_name(
   14050           1 :                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
   14051             : 
   14052           1 :         return ret;
   14053             : }
   14054             : 
   14055           2 : static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
   14056             : {
   14057           2 :         if (a.length != b.length) {
   14058           0 :                 printf("a.length=%d != b.length=%d\n",
   14059           0 :                        (int)a.length, (int)b.length);
   14060           0 :                 return false;
   14061             :         }
   14062           2 :         if (memcmp(a.data, b.data, a.length) != 0) {
   14063           0 :                 printf("a.data and b.data differ\n");
   14064           0 :                 return false;
   14065             :         }
   14066           0 :         return true;
   14067             : }
   14068             : 
   14069           1 : static bool run_local_memcache(int dummy)
   14070             : {
   14071           1 :         struct memcache *cache;
   14072           1 :         DATA_BLOB k1, k2, k3, k4, k5;
   14073           1 :         DATA_BLOB d1, d3;
   14074           1 :         DATA_BLOB v1, v3;
   14075             : 
   14076           1 :         TALLOC_CTX *mem_ctx;
   14077           1 :         char *ptr1 = NULL;
   14078           1 :         char *ptr2 = NULL;
   14079           1 :         char *ptr3 = NULL;
   14080             : 
   14081           1 :         char *str1, *str2;
   14082           1 :         size_t size1, size2;
   14083           1 :         bool ret = false;
   14084             : 
   14085           1 :         mem_ctx = talloc_init("foo");
   14086           1 :         if (mem_ctx == NULL) {
   14087           0 :                 return false;
   14088             :         }
   14089             : 
   14090             :         /* STAT_CACHE TESTS */
   14091             : 
   14092           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14093             : 
   14094           1 :         if (cache == NULL) {
   14095           0 :                 printf("memcache_init failed\n");
   14096           0 :                 return false;
   14097             :         }
   14098             : 
   14099           1 :         d1 = data_blob_const("d1", 2);
   14100           1 :         d3 = data_blob_const("d3", 2);
   14101             : 
   14102           1 :         k1 = data_blob_const("d1", 2);
   14103           1 :         k2 = data_blob_const("d2", 2);
   14104           1 :         k3 = data_blob_const("d3", 2);
   14105           1 :         k4 = data_blob_const("d4", 2);
   14106           1 :         k5 = data_blob_const("d5", 2);
   14107             : 
   14108           1 :         memcache_add(cache, STAT_CACHE, k1, d1);
   14109             : 
   14110           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
   14111           0 :                 printf("could not find k1\n");
   14112           0 :                 return false;
   14113             :         }
   14114           1 :         if (!data_blob_equal(d1, v1)) {
   14115           0 :                 return false;
   14116             :         }
   14117             : 
   14118           1 :         memcache_add(cache, STAT_CACHE, k1, d3);
   14119             : 
   14120           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
   14121           0 :                 printf("could not find replaced k1\n");
   14122           0 :                 return false;
   14123             :         }
   14124           1 :         if (!data_blob_equal(d3, v3)) {
   14125           0 :                 return false;
   14126             :         }
   14127             : 
   14128           1 :         TALLOC_FREE(cache);
   14129             : 
   14130             :         /* GETWD_CACHE TESTS */
   14131           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14132           1 :         if (str1 == NULL) {
   14133           0 :                 return false;
   14134             :         }
   14135           1 :         ptr2 = str1; /* Keep an alias for comparison. */
   14136             : 
   14137           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14138           1 :         if (str2 == NULL) {
   14139           0 :                 return false;
   14140             :         }
   14141             : 
   14142           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14143           1 :         if (cache == NULL) {
   14144           0 :                 printf("memcache_init failed\n");
   14145           0 :                 return false;
   14146             :         }
   14147             : 
   14148           1 :         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
   14149             :         /* str1 == NULL now. */
   14150           1 :         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14151           1 :         if (ptr1 == NULL) {
   14152           0 :                 printf("could not find k2\n");
   14153           0 :                 return false;
   14154             :         }
   14155           1 :         if (ptr1 != ptr2) {
   14156           0 :                 printf("fetch of k2 got wrong string\n");
   14157           0 :                 return false;
   14158             :         }
   14159             : 
   14160             :         /* Add a blob to ensure k2 gets purged. */
   14161           1 :         d3 = data_blob_talloc_zero(mem_ctx, 180);
   14162           1 :         memcache_add(cache, STAT_CACHE, k3, d3);
   14163             : 
   14164           1 :         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14165           1 :         if (ptr2 != NULL) {
   14166           0 :                 printf("Did find k2, should have been purged\n");
   14167           0 :                 return false;
   14168             :         }
   14169             : 
   14170             :         /*
   14171             :          * Test that talloc size also is accounted in memcache and
   14172             :          * causes purge of other object.
   14173             :          */
   14174             : 
   14175           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14176           1 :         str2 = talloc_zero_size(mem_ctx, 100);
   14177             : 
   14178           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14179           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
   14180             : 
   14181           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14182           1 :         if (ptr3 != NULL) {
   14183           0 :                 printf("Did find k4, should have been purged\n");
   14184           0 :                 return false;
   14185             :         }
   14186             : 
   14187             :         /*
   14188             :          * Test that adding a duplicate non-talloced
   14189             :          * key/value on top of a talloced key/value takes account
   14190             :          * of the talloc_freed value size.
   14191             :          */
   14192           1 :         TALLOC_FREE(cache);
   14193           1 :         TALLOC_FREE(mem_ctx);
   14194             : 
   14195           1 :         mem_ctx = talloc_init("key_replace");
   14196           1 :         if (mem_ctx == NULL) {
   14197           0 :                 return false;
   14198             :         }
   14199             : 
   14200           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14201           1 :         if (cache == NULL) {
   14202           0 :                 return false;
   14203             :         }
   14204             : 
   14205             :         /*
   14206             :          * Add a 100 byte talloced string. This will
   14207             :          * store a (4 or 8 byte) pointer and record the
   14208             :          * total talloced size.
   14209             :          */
   14210           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14211           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14212             :         /*
   14213             :          * Now overwrite with a small talloced
   14214             :          * value. This should fit in the existing size
   14215             :          * and the total talloced size should be removed
   14216             :          * from the cache size.
   14217             :          */
   14218           1 :         str1 = talloc_zero_size(mem_ctx, 2);
   14219           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14220             :         /*
   14221             :          * Now store a 20 byte string. If the
   14222             :          * total talloced size wasn't accounted for
   14223             :          * and removed in the overwrite, then this
   14224             :          * will evict k4.
   14225             :          */
   14226           1 :         str2 = talloc_zero_size(mem_ctx, 20);
   14227           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
   14228             : 
   14229           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14230           1 :         if (ptr3 == NULL) {
   14231           0 :                 printf("Did not find k4, should not have been purged\n");
   14232           0 :                 return false;
   14233             :         }
   14234             : 
   14235           1 :         TALLOC_FREE(cache);
   14236           1 :         TALLOC_FREE(mem_ctx);
   14237             : 
   14238           1 :         mem_ctx = talloc_init("foo");
   14239           1 :         if (mem_ctx == NULL) {
   14240           0 :                 return false;
   14241             :         }
   14242             : 
   14243           1 :         cache = memcache_init(NULL, 0);
   14244           1 :         if (cache == NULL) {
   14245           0 :                 return false;
   14246             :         }
   14247             : 
   14248           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14249           1 :         if (str1 == NULL) {
   14250           0 :                 return false;
   14251             :         }
   14252           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14253           1 :         if (str2 == NULL) {
   14254           0 :                 return false;
   14255             :         }
   14256           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14257             :                             data_blob_string_const("torture"), &str1);
   14258           1 :         size1 = talloc_total_size(cache);
   14259             : 
   14260           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14261             :                             data_blob_string_const("torture"), &str2);
   14262           1 :         size2 = talloc_total_size(cache);
   14263             : 
   14264           1 :         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
   14265             : 
   14266           1 :         if (size2 > size1) {
   14267           0 :                 printf("memcache leaks memory!\n");
   14268           0 :                 goto fail;
   14269             :         }
   14270             : 
   14271           0 :         ret = true;
   14272           1 :  fail:
   14273           1 :         TALLOC_FREE(cache);
   14274           1 :         return ret;
   14275             : }
   14276             : 
   14277         200 : static void wbclient_done(struct tevent_req *req)
   14278             : {
   14279           0 :         wbcErr wbc_err;
   14280           0 :         struct winbindd_response *wb_resp;
   14281         200 :         int *i = (int *)tevent_req_callback_data_void(req);
   14282             : 
   14283         200 :         wbc_err = wb_trans_recv(req, req, &wb_resp);
   14284         200 :         TALLOC_FREE(req);
   14285         200 :         *i += 1;
   14286         200 :         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
   14287         200 : }
   14288             : 
   14289           2 : static bool run_wbclient_multi_ping(int dummy)
   14290             : {
   14291           0 :         struct tevent_context *ev;
   14292           0 :         struct wb_context **wb_ctx;
   14293           0 :         struct winbindd_request wb_req;
   14294           2 :         bool result = false;
   14295           0 :         int i, j;
   14296             : 
   14297           2 :         BlockSignals(True, SIGPIPE);
   14298             : 
   14299           2 :         ev = tevent_context_init(talloc_tos());
   14300           2 :         if (ev == NULL) {
   14301           0 :                 goto fail;
   14302             :         }
   14303             : 
   14304           2 :         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
   14305           2 :         if (wb_ctx == NULL) {
   14306           0 :                 goto fail;
   14307             :         }
   14308             : 
   14309           2 :         ZERO_STRUCT(wb_req);
   14310           2 :         wb_req.cmd = WINBINDD_PING;
   14311             : 
   14312           2 :         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
   14313             : 
   14314           4 :         for (i=0; i<torture_nprocs; i++) {
   14315           2 :                 wb_ctx[i] = wb_context_init(ev, NULL);
   14316           2 :                 if (wb_ctx[i] == NULL) {
   14317           0 :                         goto fail;
   14318             :                 }
   14319         202 :                 for (j=0; j<torture_numops; j++) {
   14320           0 :                         struct tevent_req *req;
   14321         200 :                         req = wb_trans_send(ev, ev, wb_ctx[i],
   14322         200 :                                             (j % 2) == 0, &wb_req);
   14323         200 :                         if (req == NULL) {
   14324           0 :                                 goto fail;
   14325             :                         }
   14326         200 :                         tevent_req_set_callback(req, wbclient_done, &i);
   14327             :                 }
   14328             :         }
   14329             : 
   14330           2 :         i = 0;
   14331             : 
   14332         818 :         while (i < torture_nprocs * torture_numops) {
   14333         816 :                 tevent_loop_once(ev);
   14334             :         }
   14335             : 
   14336           2 :         result = true;
   14337           2 :  fail:
   14338           2 :         TALLOC_FREE(ev);
   14339           2 :         return result;
   14340             : }
   14341             : 
   14342           0 : static bool dbtrans_inc(struct db_context *db)
   14343             : {
   14344           0 :         struct db_record *rec;
   14345           0 :         uint32_t val;
   14346           0 :         bool ret = false;
   14347           0 :         NTSTATUS status;
   14348           0 :         TDB_DATA value;
   14349             : 
   14350           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14351           0 :         if (rec == NULL) {
   14352           0 :                 printf(__location__ "fetch_lock failed\n");
   14353           0 :                 return false;
   14354             :         }
   14355             : 
   14356           0 :         value = dbwrap_record_get_value(rec);
   14357             : 
   14358           0 :         if (value.dsize != sizeof(uint32_t)) {
   14359           0 :                 printf(__location__ "value.dsize = %d\n",
   14360           0 :                        (int)value.dsize);
   14361           0 :                 goto fail;
   14362             :         }
   14363             : 
   14364           0 :         memcpy(&val, value.dptr, sizeof(val));
   14365           0 :         val += 1;
   14366             : 
   14367           0 :         status = dbwrap_record_store(
   14368             :                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
   14369           0 :         if (!NT_STATUS_IS_OK(status)) {
   14370           0 :                 printf(__location__ "store failed: %s\n",
   14371             :                        nt_errstr(status));
   14372           0 :                 goto fail;
   14373             :         }
   14374             : 
   14375           0 :         ret = true;
   14376           0 : fail:
   14377           0 :         TALLOC_FREE(rec);
   14378           0 :         return ret;
   14379             : }
   14380             : 
   14381           0 : static bool run_local_dbtrans(int dummy)
   14382             : {
   14383           0 :         struct db_context *db;
   14384           0 :         struct db_record *rec;
   14385           0 :         NTSTATUS status;
   14386           0 :         uint32_t initial;
   14387           0 :         int res;
   14388           0 :         TDB_DATA value;
   14389             : 
   14390           0 :         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
   14391             :                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
   14392             :                      DBWRAP_FLAG_NONE);
   14393           0 :         if (db == NULL) {
   14394           0 :                 printf("Could not open transtest.db\n");
   14395           0 :                 return false;
   14396             :         }
   14397             : 
   14398           0 :         res = dbwrap_transaction_start(db);
   14399           0 :         if (res != 0) {
   14400           0 :                 printf(__location__ "transaction_start failed\n");
   14401           0 :                 return false;
   14402             :         }
   14403             : 
   14404           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14405           0 :         if (rec == NULL) {
   14406           0 :                 printf(__location__ "fetch_lock failed\n");
   14407           0 :                 return false;
   14408             :         }
   14409             : 
   14410           0 :         value = dbwrap_record_get_value(rec);
   14411             : 
   14412           0 :         if (value.dptr == NULL) {
   14413           0 :                 initial = 0;
   14414           0 :                 status = dbwrap_record_store(
   14415             :                         rec, make_tdb_data((uint8_t *)&initial,
   14416             :                                            sizeof(initial)),
   14417             :                         0);
   14418           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14419           0 :                         printf(__location__ "store returned %s\n",
   14420             :                                nt_errstr(status));
   14421           0 :                         return false;
   14422             :                 }
   14423             :         }
   14424             : 
   14425           0 :         TALLOC_FREE(rec);
   14426             : 
   14427           0 :         res = dbwrap_transaction_commit(db);
   14428           0 :         if (res != 0) {
   14429           0 :                 printf(__location__ "transaction_commit failed\n");
   14430           0 :                 return false;
   14431             :         }
   14432             : 
   14433           0 :         while (true) {
   14434           0 :                 uint32_t val, val2;
   14435           0 :                 int i;
   14436             : 
   14437           0 :                 res = dbwrap_transaction_start(db);
   14438           0 :                 if (res != 0) {
   14439           0 :                         printf(__location__ "transaction_start failed\n");
   14440           0 :                         break;
   14441             :                 }
   14442             : 
   14443           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
   14444           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14445           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14446             :                                nt_errstr(status));
   14447           0 :                         break;
   14448             :                 }
   14449             : 
   14450           0 :                 for (i=0; i<10; i++) {
   14451           0 :                         if (!dbtrans_inc(db)) {
   14452           0 :                                 return false;
   14453             :                         }
   14454             :                 }
   14455             : 
   14456           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
   14457           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14458           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14459             :                                nt_errstr(status));
   14460           0 :                         break;
   14461             :                 }
   14462             : 
   14463           0 :                 if (val2 != val + 10) {
   14464           0 :                         printf(__location__ "val=%d, val2=%d\n",
   14465             :                                (int)val, (int)val2);
   14466           0 :                         break;
   14467             :                 }
   14468             : 
   14469           0 :                 printf("val2=%d\r", val2);
   14470             : 
   14471           0 :                 res = dbwrap_transaction_commit(db);
   14472           0 :                 if (res != 0) {
   14473           0 :                         printf(__location__ "transaction_commit failed\n");
   14474           0 :                         break;
   14475             :                 }
   14476             :         }
   14477             : 
   14478           0 :         TALLOC_FREE(db);
   14479           0 :         return true;
   14480             : }
   14481             : 
   14482             : /*
   14483             :  * Just a dummy test to be run under a debugger. There's no real way
   14484             :  * to inspect the tevent_poll specific function from outside of
   14485             :  * tevent_poll.c.
   14486             :  */
   14487             : 
   14488           1 : static bool run_local_tevent_poll(int dummy)
   14489             : {
   14490           1 :         struct tevent_context *ev;
   14491           1 :         struct tevent_fd *fd1, *fd2;
   14492           1 :         bool result = false;
   14493             : 
   14494           1 :         ev = tevent_context_init_byname(NULL, "poll");
   14495           1 :         if (ev == NULL) {
   14496           0 :                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
   14497           0 :                 goto fail;
   14498             :         }
   14499             : 
   14500           1 :         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
   14501           1 :         if (fd1 == NULL) {
   14502           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14503           0 :                 goto fail;
   14504             :         }
   14505           1 :         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
   14506           1 :         if (fd2 == NULL) {
   14507           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14508           0 :                 goto fail;
   14509             :         }
   14510           1 :         TALLOC_FREE(fd2);
   14511             : 
   14512           1 :         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
   14513           1 :         if (fd2 == NULL) {
   14514           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14515           0 :                 goto fail;
   14516             :         }
   14517             : 
   14518           0 :         result = true;
   14519           1 : fail:
   14520           1 :         TALLOC_FREE(ev);
   14521           1 :         return result;
   14522             : }
   14523             : 
   14524           1 : static bool run_local_hex_encode_buf(int dummy)
   14525             : {
   14526           1 :         char buf[17];
   14527           1 :         uint8_t src[8];
   14528           1 :         size_t i;
   14529             : 
   14530           9 :         for (i=0; i<sizeof(src); i++) {
   14531           8 :                 src[i] = i;
   14532             :         }
   14533           1 :         hex_encode_buf(buf, src, sizeof(src));
   14534           1 :         if (strcmp(buf, "0001020304050607") != 0) {
   14535           0 :                 return false;
   14536             :         }
   14537           1 :         hex_encode_buf(buf, NULL, 0);
   14538           1 :         if (buf[0] != '\0') {
   14539           0 :                 return false;
   14540             :         }
   14541           0 :         return true;
   14542             : }
   14543             : 
   14544             : static const char *remove_duplicate_addrs2_test_strings_vector[] = {
   14545             :         "0.0.0.0",
   14546             :         "::0",
   14547             :         "1.2.3.1",
   14548             :         "0.0.0.0",
   14549             :         "0.0.0.0",
   14550             :         "1.2.3.2",
   14551             :         "1.2.3.3",
   14552             :         "1.2.3.4",
   14553             :         "1.2.3.5",
   14554             :         "::0",
   14555             :         "1.2.3.6",
   14556             :         "1.2.3.7",
   14557             :         "::0",
   14558             :         "::0",
   14559             :         "::0",
   14560             :         "1.2.3.8",
   14561             :         "1.2.3.9",
   14562             :         "1.2.3.10",
   14563             :         "1.2.3.11",
   14564             :         "1.2.3.12",
   14565             :         "1.2.3.13",
   14566             :         "1001:1111:1111:1000:0:1111:1111:1111",
   14567             :         "1.2.3.1",
   14568             :         "1.2.3.2",
   14569             :         "1.2.3.3",
   14570             :         "1.2.3.12",
   14571             :         "::0",
   14572             :         "::0"
   14573             : };
   14574             : 
   14575             : static const char *remove_duplicate_addrs2_test_strings_result[] = {
   14576             :         "1.2.3.1",
   14577             :         "1.2.3.2",
   14578             :         "1.2.3.3",
   14579             :         "1.2.3.4",
   14580             :         "1.2.3.5",
   14581             :         "1.2.3.6",
   14582             :         "1.2.3.7",
   14583             :         "1.2.3.8",
   14584             :         "1.2.3.9",
   14585             :         "1.2.3.10",
   14586             :         "1.2.3.11",
   14587             :         "1.2.3.12",
   14588             :         "1.2.3.13",
   14589             :         "1001:1111:1111:1000:0:1111:1111:1111"
   14590             : };
   14591             : 
   14592           1 : static bool run_local_remove_duplicate_addrs2(int dummy)
   14593             : {
   14594           1 :         struct samba_sockaddr test_vector[28];
   14595           1 :         size_t count, i;
   14596             : 
   14597             :         /* Construct the sockaddr_storage test vector. */
   14598          29 :         for (i = 0; i < 28; i++) {
   14599          28 :                 struct addrinfo hints;
   14600          28 :                 struct addrinfo *res = NULL;
   14601          28 :                 int ret;
   14602             : 
   14603          28 :                 memset(&hints, '\0', sizeof(hints));
   14604          28 :                 hints.ai_flags = AI_NUMERICHOST;
   14605          28 :                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
   14606             :                                 NULL,
   14607             :                                 &hints,
   14608             :                                 &res);
   14609          28 :                 if (ret) {
   14610           0 :                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
   14611             :                                 remove_duplicate_addrs2_test_strings_vector[i]);
   14612           0 :                         return false;
   14613             :                 }
   14614          28 :                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
   14615          28 :                 memcpy(&test_vector[i].u.ss,
   14616          28 :                         res->ai_addr,
   14617          28 :                         res->ai_addrlen);
   14618          28 :                 freeaddrinfo(res);
   14619             :         }
   14620             : 
   14621           1 :         count = remove_duplicate_addrs2(test_vector, i);
   14622             : 
   14623           1 :         if (count != 14) {
   14624           0 :                 fprintf(stderr, "count wrong (%zu) should be 14\n",
   14625             :                         count);
   14626           0 :                 return false;
   14627             :         }
   14628             : 
   14629          15 :         for (i = 0; i < count; i++) {
   14630          14 :                 char addr[INET6_ADDRSTRLEN];
   14631             : 
   14632          14 :                 print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
   14633             : 
   14634          14 :                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
   14635           0 :                         fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
   14636             :                                 i,
   14637             :                                 addr,
   14638             :                                 remove_duplicate_addrs2_test_strings_result[i]);
   14639           0 :                         return false;
   14640             :                 }
   14641             :         }
   14642             : 
   14643           1 :         printf("run_local_remove_duplicate_addrs2: success\n");
   14644           1 :         return true;
   14645             : }
   14646             : 
   14647           0 : static bool run_local_tdb_opener(int dummy)
   14648             : {
   14649           0 :         TDB_CONTEXT *t;
   14650           0 :         unsigned v = 0;
   14651             : 
   14652           0 :         while (1) {
   14653           0 :                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
   14654             :                              O_RDWR|O_CREAT, 0755);
   14655           0 :                 if (t == NULL) {
   14656           0 :                         perror("tdb_open failed");
   14657           0 :                         return false;
   14658             :                 }
   14659           0 :                 tdb_close(t);
   14660             : 
   14661           0 :                 v += 1;
   14662           0 :                 printf("\r%u", v);
   14663             :         }
   14664             :         return true;
   14665             : }
   14666             : 
   14667           0 : static bool run_local_tdb_writer(int dummy)
   14668             : {
   14669           0 :         TDB_CONTEXT *t;
   14670           0 :         unsigned v = 0;
   14671           0 :         TDB_DATA val;
   14672             : 
   14673           0 :         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
   14674           0 :         if (t == 0) {
   14675           0 :                 perror("tdb_open failed");
   14676           0 :                 return 1;
   14677             :         }
   14678             : 
   14679           0 :         val.dptr = (uint8_t *)&v;
   14680           0 :         val.dsize = sizeof(v);
   14681             : 
   14682           0 :         while (1) {
   14683           0 :                 TDB_DATA data;
   14684           0 :                 int ret;
   14685             : 
   14686           0 :                 ret = tdb_store(t, val, val, 0);
   14687           0 :                 if (ret != 0) {
   14688           0 :                         printf("%s\n", tdb_errorstr(t));
   14689             :                 }
   14690           0 :                 v += 1;
   14691           0 :                 printf("\r%u", v);
   14692             : 
   14693           0 :                 data = tdb_fetch(t, val);
   14694           0 :                 if (data.dptr != NULL) {
   14695           0 :                         SAFE_FREE(data.dptr);
   14696             :                 }
   14697             :         }
   14698             :         return true;
   14699             : }
   14700             : 
   14701           1 : static bool run_local_canonicalize_path(int dummy)
   14702             : {
   14703           1 :         const char *src[] = {
   14704             :                         "/foo/..",
   14705             :                         "/..",
   14706             :                         "/foo/bar/../baz",
   14707             :                         "/foo/././",
   14708             :                         "/../foo",
   14709             :                         ".././././",
   14710             :                         ".././././../../../boo",
   14711             :                         "./..",
   14712             :                         "/",
   14713             :                         "/../../",
   14714             :                         "/foo/../",
   14715             :                         "/./././",
   14716             :                         "/./././.",
   14717             :                         "/.../././.",
   14718             :                         "/./././.foo",
   14719             :                         "/./././.foo.",
   14720             :                         "/./././foo.",
   14721             :                         "/foo/bar/..",
   14722             :                         "/foo/bar/../baz/",
   14723             :                         "////////////////",
   14724             :                         "/////////./././././.",
   14725             :                         "/./.././../.boo/../baz",
   14726             :                         "/a/component/path",
   14727             :                         "/a/component/path/",
   14728             :                         "/a/component/path/..",
   14729             :                         "/a/component/../path/",
   14730             :                         "///a/./././///component/../////path/",
   14731             :                         NULL
   14732             :                         };
   14733           1 :         const char *dst[] = {
   14734             :                         "/",
   14735             :                         "/",
   14736             :                         "/foo/baz",
   14737             :                         "/foo",
   14738             :                         "/foo",
   14739             :                         "/",
   14740             :                         "/boo",
   14741             :                         "/",
   14742             :                         "/",
   14743             :                         "/",
   14744             :                         "/",
   14745             :                         "/",
   14746             :                         "/",
   14747             :                         "/...",
   14748             :                         "/.foo",
   14749             :                         "/.foo.",
   14750             :                         "/foo.",
   14751             :                         "/foo",
   14752             :                         "/foo/baz",
   14753             :                         "/",
   14754             :                         "/",
   14755             :                         "/baz",
   14756             :                         "/a/component/path",
   14757             :                         "/a/component/path",
   14758             :                         "/a/component",
   14759             :                         "/a/path",
   14760             :                         "/a/path",
   14761             :                         NULL
   14762             :                         };
   14763           1 :         unsigned int i;
   14764             : 
   14765          28 :         for (i = 0; src[i] != NULL; i++) {
   14766          27 :                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
   14767          27 :                 if (d == NULL) {
   14768           0 :                         perror("talloc fail\n");
   14769           0 :                         return false;
   14770             :                 }
   14771          27 :                 if (strcmp(d, dst[i]) != 0) {
   14772           0 :                         d_fprintf(stderr,
   14773             :                                 "canonicalize mismatch %s -> %s != %s",
   14774             :                                 src[i], d, dst[i]);
   14775           0 :                         return false;
   14776             :                 }
   14777          27 :                 talloc_free(d);
   14778             :         }
   14779           0 :         return true;
   14780             : }
   14781             : struct session_setup_nt1_truncated_state {
   14782             :         uint16_t vwv[13];
   14783             :         uint8_t bytes[20];
   14784             : };
   14785             : 
   14786             : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
   14787             : 
   14788           2 : static struct tevent_req *smb1_session_setup_nt1_truncated_send(
   14789             :                 TALLOC_CTX *mem_ctx,
   14790             :                 struct tevent_context *ev,
   14791             :                 struct smbXcli_conn *conn)
   14792             : {
   14793           2 :         uint16_t *vwv = NULL;
   14794           2 :         uint8_t *bytes = NULL;
   14795           2 :         const char *pass = "12345678";
   14796           2 :         const char *uname = "z";
   14797           2 :         struct session_setup_nt1_truncated_state *state = NULL;
   14798           2 :         struct tevent_req *req = NULL;
   14799           2 :         struct tevent_req *subreq = NULL;
   14800             : 
   14801           2 :         req = tevent_req_create(mem_ctx,
   14802             :                                 &state,
   14803             :                                 struct session_setup_nt1_truncated_state);
   14804           2 :         if (req == NULL) {
   14805           0 :                 return NULL;
   14806             :         }
   14807           2 :         vwv = &state->vwv[0];
   14808           2 :         bytes = &state->bytes[0];
   14809             : 
   14810           2 :         SCVAL(vwv+0,  0, 0xff);
   14811           2 :         SCVAL(vwv+0,  1, 0);
   14812           2 :         SSVAL(vwv+1,  0, 0);
   14813           2 :         SSVAL(vwv+2,  0, 8192);
   14814           2 :         SSVAL(vwv+3,  0, 2);
   14815           2 :         SSVAL(vwv+4,  0, 1);
   14816           2 :         SIVAL(vwv+5,  0, 0);
   14817           2 :         SSVAL(vwv+7,  0, strlen(pass)); /* OEMPasswordLen */
   14818           2 :         SSVAL(vwv+8,  0, 0); /* UnicodePasswordLen */
   14819           2 :         SSVAL(vwv+9,  0, 0); /* reserved */
   14820           2 :         SSVAL(vwv+10, 0, 0); /* reserved */
   14821           2 :         SIVAL(vwv+11, 0, CAP_STATUS32);
   14822             : 
   14823           2 :         memcpy(bytes, pass, strlen(pass));
   14824           2 :         bytes += strlen(pass);
   14825           2 :         memcpy(bytes, uname, strlen(uname)+1);
   14826             : 
   14827           2 :         subreq = smb1cli_req_send(state, ev, conn,
   14828             :                                   SMBsesssetupX,
   14829             :                                   0, /*  additional_flags */
   14830             :                                   0, /*  clear_flags */
   14831             :                                   0, /*  additional_flags2 */
   14832             :                                   0, /*  clear_flags2 */
   14833             :                                   10000, /* timeout_msec */
   14834           2 :                                   getpid(),
   14835             :                                   NULL, /* tcon */
   14836             :                                   NULL, /* session */
   14837             :                                   13, /* wct */
   14838           2 :                                   state->vwv,
   14839           2 :                                   strlen(pass), /* Truncate length at password. */
   14840           2 :                                   state->bytes);
   14841           2 :         if (tevent_req_nomem(subreq, req)) {
   14842           0 :                 return tevent_req_post(req, ev);
   14843             :         }
   14844           2 :         tevent_req_set_callback(subreq,
   14845             :                                 smb1_session_setup_nt1_truncated_done,
   14846             :                                 req);
   14847           2 :         return req;
   14848             : }
   14849             : 
   14850           2 : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
   14851             : {
   14852           0 :         struct tevent_req *req =
   14853           2 :                 tevent_req_callback_data(subreq,
   14854             :                 struct tevent_req);
   14855           0 :         struct session_setup_nt1_truncated_state *state =
   14856           2 :                 tevent_req_data(req,
   14857             :                 struct session_setup_nt1_truncated_state);
   14858           0 :         NTSTATUS status;
   14859           2 :         struct smb1cli_req_expected_response expected[] = {
   14860             :         {
   14861             :                 .status = NT_STATUS_OK,
   14862             :                 .wct    = 3,
   14863             :         },
   14864             :         };
   14865             : 
   14866           2 :         status = smb1cli_req_recv(subreq, state,
   14867             :                                   NULL,
   14868             :                                   NULL,
   14869             :                                   NULL,
   14870             :                                   NULL,
   14871             :                                   NULL, /* pvwv_offset */
   14872             :                                   NULL,
   14873             :                                   NULL,
   14874             :                                   NULL, /* pbytes_offset */
   14875             :                                   NULL,
   14876             :                                   expected, ARRAY_SIZE(expected));
   14877           2 :         TALLOC_FREE(subreq);
   14878           2 :         if (tevent_req_nterror(req, status)) {
   14879           0 :                 return;
   14880             :         }
   14881           2 :         tevent_req_done(req);
   14882             : }
   14883             : 
   14884           2 : static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
   14885             : {
   14886           2 :         return tevent_req_simple_recv_ntstatus(req);
   14887             : }
   14888             : 
   14889           2 : static bool run_smb1_truncated_sesssetup(int dummy)
   14890             : {
   14891           0 :         struct tevent_context *ev;
   14892           0 :         struct tevent_req *req;
   14893           0 :         struct smbXcli_conn *conn;
   14894           0 :         struct sockaddr_storage ss;
   14895           0 :         NTSTATUS status;
   14896           0 :         int fd;
   14897           0 :         bool ok;
   14898             : 
   14899           2 :         printf("Starting send truncated SMB1 sesssetup.\n");
   14900             : 
   14901           2 :         ok = resolve_name(host, &ss, 0x20, true);
   14902           2 :         if (!ok) {
   14903           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14904           0 :                 return false;
   14905             :         }
   14906             : 
   14907           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14908           2 :         if (!NT_STATUS_IS_OK(status)) {
   14909           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14910             :                           nt_errstr(status));
   14911           0 :                 return false;
   14912             :         }
   14913             : 
   14914           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14915             :                                    NULL, 0, NULL);
   14916           2 :         if (conn == NULL) {
   14917           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14918           0 :                 return false;
   14919             :         }
   14920             : 
   14921           2 :         status = smbXcli_negprot(conn,
   14922             :                                  0,
   14923             :                                  PROTOCOL_NT1,
   14924             :                                  PROTOCOL_NT1,
   14925             :                                  NULL,
   14926             :                                  NULL,
   14927             :                                  NULL);
   14928           2 :         if (!NT_STATUS_IS_OK(status)) {
   14929           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   14930           0 :                 return false;
   14931             :         }
   14932             : 
   14933           2 :         ev = samba_tevent_context_init(talloc_tos());
   14934           2 :         if (ev == NULL) {
   14935           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14936           0 :                 return false;
   14937             :         }
   14938             : 
   14939           2 :         req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
   14940           2 :         if (req == NULL) {
   14941           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
   14942           0 :                 return false;
   14943             :         }
   14944             : 
   14945           2 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   14946           2 :         if (!ok) {
   14947           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   14948             :                         nt_errstr(status));
   14949           0 :                 return false;
   14950             :         }
   14951             : 
   14952           2 :         status = smb1_session_setup_nt1_truncated_recv(req);
   14953           2 :         if (!NT_STATUS_IS_OK(status)) {
   14954           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
   14955             :                           "%s, expected NT_STATUS_OK\n",
   14956             :                           nt_errstr(status));
   14957           0 :                 return false;
   14958             :         }
   14959             : 
   14960           2 :         TALLOC_FREE(conn);
   14961           2 :         return true;
   14962             : }
   14963             : 
   14964             : struct smb1_negotiate_exit_state {
   14965             :         int dummy;
   14966             : };
   14967             : 
   14968             : static void smb1_negotiate_exit_done(struct tevent_req *subreq);
   14969             : 
   14970           4 : static struct tevent_req *smb1_negotiate_exit_send(
   14971             :                 TALLOC_CTX *mem_ctx,
   14972             :                 struct tevent_context *ev,
   14973             :                 struct smbXcli_conn *conn)
   14974             : {
   14975           4 :         struct smb1_negotiate_exit_state *state = NULL;
   14976           4 :         struct tevent_req *req = NULL;
   14977           4 :         struct tevent_req *subreq = NULL;
   14978             : 
   14979           4 :         req = tevent_req_create(mem_ctx,
   14980             :                                 &state,
   14981             :                                 struct smb1_negotiate_exit_state);
   14982           4 :         if (req == NULL) {
   14983           0 :                 return NULL;
   14984             :         }
   14985           4 :         subreq = smb1cli_req_send(state, ev, conn,
   14986             :                                   SMBexit,
   14987             :                                   0, /*  additional_flags */
   14988             :                                   0, /*  clear_flags */
   14989             :                                   0, /*  additional_flags2 */
   14990             :                                   0, /*  clear_flags2 */
   14991             :                                   10000, /* timeout_msec */
   14992           4 :                                   getpid(),
   14993             :                                   NULL, /* tcon */
   14994             :                                   NULL, /* session */
   14995             :                                   0, /* wct */
   14996             :                                   NULL,
   14997             :                                   0,
   14998             :                                   NULL);
   14999           4 :         if (tevent_req_nomem(subreq, req)) {
   15000           0 :                 return tevent_req_post(req, ev);
   15001             :         }
   15002           4 :         tevent_req_set_callback(subreq,
   15003             :                                 smb1_negotiate_exit_done,
   15004             :                                 req);
   15005           4 :         return req;
   15006             : }
   15007             : 
   15008           4 : static void smb1_negotiate_exit_done(struct tevent_req *subreq)
   15009             : {
   15010           0 :         struct tevent_req *req =
   15011           4 :                 tevent_req_callback_data(subreq,
   15012             :                 struct tevent_req);
   15013           0 :         struct smb1_negotiate_exit_state *state =
   15014           4 :                 tevent_req_data(req,
   15015             :                 struct smb1_negotiate_exit_state);
   15016           0 :         NTSTATUS status;
   15017           4 :         struct smb1cli_req_expected_response expected[] = {
   15018             :         {
   15019             :                 .status = NT_STATUS_OK,
   15020             :                 .wct    = 0,
   15021             :         },
   15022             :         };
   15023             : 
   15024           4 :         status = smb1cli_req_recv(subreq, state,
   15025             :                                   NULL,
   15026             :                                   NULL,
   15027             :                                   NULL,
   15028             :                                   NULL,
   15029             :                                   NULL, /* pvwv_offset */
   15030             :                                   NULL,
   15031             :                                   NULL,
   15032             :                                   NULL, /* pbytes_offset */
   15033             :                                   NULL,
   15034             :                                   expected, ARRAY_SIZE(expected));
   15035           4 :         TALLOC_FREE(subreq);
   15036           4 :         if (tevent_req_nterror(req, status)) {
   15037           4 :                 return;
   15038             :         }
   15039           0 :         tevent_req_done(req);
   15040             : }
   15041             : 
   15042           4 : static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
   15043             : {
   15044           4 :         return tevent_req_simple_recv_ntstatus(req);
   15045             : }
   15046             : 
   15047           4 : static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
   15048             :                          struct tevent_context *ev,
   15049             :                          struct smbXcli_conn *conn)
   15050             : {
   15051           0 :         struct tevent_req *req;
   15052           0 :         bool ok;
   15053           0 :         NTSTATUS status;
   15054           4 :         NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
   15055             : 
   15056           4 :         req = smb1_negotiate_exit_send(ev, ev, conn);
   15057           4 :         if (req == NULL) {
   15058           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
   15059           0 :                 return false;
   15060             :         }
   15061             : 
   15062           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15063           4 :         if (!ok) {
   15064           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   15065             :                         nt_errstr(status));
   15066           0 :                 return false;
   15067             :         }
   15068             : 
   15069           4 :         status = smb1_negotiate_exit_recv(req);
   15070           4 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   15071           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
   15072             :                           "%s, expected ERRSRV, ERRinvnid\n",
   15073             :                           nt_errstr(status));
   15074           0 :                 return false;
   15075             :         }
   15076           4 :         return true;
   15077             : }
   15078             : 
   15079           2 : static bool run_smb1_negotiate_exit(int dummy)
   15080             : {
   15081           0 :         struct tevent_context *ev;
   15082           0 :         struct smbXcli_conn *conn;
   15083           0 :         struct sockaddr_storage ss;
   15084           0 :         NTSTATUS status;
   15085           0 :         int fd;
   15086           0 :         bool ok;
   15087             : 
   15088           2 :         printf("Starting send SMB1 negotiate+exit.\n");
   15089             : 
   15090           2 :         ok = resolve_name(host, &ss, 0x20, true);
   15091           2 :         if (!ok) {
   15092           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15093           0 :                 return false;
   15094             :         }
   15095             : 
   15096           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15097           2 :         if (!NT_STATUS_IS_OK(status)) {
   15098           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15099             :                           nt_errstr(status));
   15100           0 :                 return false;
   15101             :         }
   15102             : 
   15103           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15104             :                                    NULL, 0, NULL);
   15105           2 :         if (conn == NULL) {
   15106           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15107           0 :                 return false;
   15108             :         }
   15109             : 
   15110           2 :         status = smbXcli_negprot(conn,
   15111             :                                  0,
   15112             :                                  PROTOCOL_NT1,
   15113             :                                  PROTOCOL_NT1,
   15114             :                                  NULL,
   15115             :                                  NULL,
   15116             :                                  NULL);
   15117           2 :         if (!NT_STATUS_IS_OK(status)) {
   15118           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   15119           0 :                 return false;
   15120             :         }
   15121             : 
   15122           2 :         ev = samba_tevent_context_init(talloc_tos());
   15123           2 :         if (ev == NULL) {
   15124           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15125           0 :                 return false;
   15126             :         }
   15127             : 
   15128             :         /*
   15129             :          * Call do_smb1_exit twice to catch a server crash, the
   15130             :          * server sends the first return code then crashes.
   15131             :          */
   15132           2 :         ok = do_smb1_exit(ev, ev, conn);
   15133           2 :         if (!ok) {
   15134           0 :                 d_fprintf(stderr, "do_smb1_exit (1) failed\n");
   15135           0 :                 return false;
   15136             :         }
   15137           2 :         ok = do_smb1_exit(ev, ev, conn);
   15138           2 :         if (!ok) {
   15139           0 :                 d_fprintf(stderr, "do_smb1_exit (2) failed\n");
   15140           0 :                 return false;
   15141             :         }
   15142             : 
   15143           2 :         TALLOC_FREE(conn);
   15144           2 :         return true;
   15145             : }
   15146             : 
   15147           2 : static bool run_smb1_negotiate_tcon(int dummy)
   15148             : {
   15149           2 :         struct cli_state *cli = NULL;
   15150           2 :         uint16_t cnum = 0;
   15151           2 :         uint16_t max_xmit = 0;
   15152           0 :         NTSTATUS status;
   15153             : 
   15154           2 :         printf("Starting send SMB1 negotiate+tcon.\n");
   15155           2 :         cli = open_nbt_connection();
   15156           2 :         if (cli == NULL) {
   15157           0 :                 d_fprintf(stderr, "open_nbt_connection failed!\n");
   15158           0 :                 return false;
   15159             :         }
   15160           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   15161             : 
   15162           2 :         status = smbXcli_negprot(cli->conn,
   15163             :                                  0,
   15164             :                                  PROTOCOL_NT1,
   15165             :                                  PROTOCOL_NT1,
   15166             :                                  NULL,
   15167             :                                  NULL,
   15168             :                                  NULL);
   15169           2 :         if (!NT_STATUS_IS_OK(status)) {
   15170           0 :                 d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
   15171             :                         nt_errstr(status));
   15172           0 :                 return false;
   15173             :         }
   15174           2 :         status = cli_raw_tcon(cli,
   15175             :                               share,
   15176             :                               "",
   15177             :                               "?????",
   15178             :                               &max_xmit,
   15179             :                               &cnum);
   15180           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
   15181           0 :                 d_fprintf(stderr, "cli_raw_tcon failed - got %s "
   15182             :                         "(should get NT_STATUS_ACCESS_DENIED)!\n",
   15183             :                         nt_errstr(status));
   15184           0 :                 return false;
   15185             :         }
   15186           2 :         return true;
   15187             : }
   15188             : 
   15189           0 : static bool run_ign_bad_negprot(int dummy)
   15190             : {
   15191           0 :         struct tevent_context *ev;
   15192           0 :         struct tevent_req *req;
   15193           0 :         struct smbXcli_conn *conn;
   15194           0 :         struct sockaddr_storage ss;
   15195           0 :         NTSTATUS status;
   15196           0 :         int fd;
   15197           0 :         bool ok;
   15198             : 
   15199           0 :         printf("starting ignore bad negprot\n");
   15200             : 
   15201           0 :         ok = resolve_name(host, &ss, 0x20, true);
   15202           0 :         if (!ok) {
   15203           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15204           0 :                 return false;
   15205             :         }
   15206             : 
   15207           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15208           0 :         if (!NT_STATUS_IS_OK(status)) {
   15209           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15210             :                           nt_errstr(status));
   15211           0 :                 return false;
   15212             :         }
   15213             : 
   15214           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15215             :                                    NULL, 0, NULL);
   15216           0 :         if (conn == NULL) {
   15217           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15218           0 :                 return false;
   15219             :         }
   15220             : 
   15221           0 :         status = smbXcli_negprot(conn,
   15222             :                                  0,
   15223             :                                  PROTOCOL_CORE,
   15224             :                                  PROTOCOL_CORE,
   15225             :                                  NULL,
   15226             :                                  NULL,
   15227             :                                  NULL);
   15228           0 :         if (NT_STATUS_IS_OK(status)) {
   15229           0 :                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
   15230           0 :                 return false;
   15231             :         }
   15232             : 
   15233           0 :         ev = samba_tevent_context_init(talloc_tos());
   15234           0 :         if (ev == NULL) {
   15235           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15236           0 :                 return false;
   15237             :         }
   15238             : 
   15239           0 :         req = smb1cli_session_setup_nt1_send(
   15240           0 :                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
   15241             :                 data_blob_null, data_blob_null, 0x40,
   15242             :                 "Windows 2000 2195", "Windows 2000 5.0");
   15243           0 :         if (req == NULL) {
   15244           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
   15245           0 :                 return false;
   15246             :         }
   15247             : 
   15248           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15249           0 :         if (!ok) {
   15250           0 :                 d_fprintf(stderr, "tevent_req_poll failed\n");
   15251           0 :                 return false;
   15252             :         }
   15253             : 
   15254           0 :         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
   15255             :                                                 NULL, NULL);
   15256           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
   15257           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
   15258             :                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
   15259             :                           nt_errstr(status));
   15260           0 :                 return false;
   15261             :         }
   15262             : 
   15263           0 :         TALLOC_FREE(conn);
   15264             : 
   15265           0 :         printf("starting ignore bad negprot\n");
   15266             : 
   15267           0 :         return true;
   15268             : }
   15269             : 
   15270             : 
   15271          16 : static double create_procs(bool (*fn)(int), bool *result)
   15272             : {
   15273           0 :         int i, status;
   15274           0 :         volatile pid_t *child_status;
   15275           0 :         volatile bool *child_status_out;
   15276           0 :         int synccount;
   15277          16 :         int tries = 8;
   15278           0 :         struct timeval start;
   15279             : 
   15280          16 :         synccount = 0;
   15281             : 
   15282          16 :         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
   15283          16 :         if (!child_status) {
   15284           0 :                 printf("Failed to setup shared memory\n");
   15285           0 :                 return -1;
   15286             :         }
   15287             : 
   15288          16 :         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
   15289          16 :         if (!child_status_out) {
   15290           0 :                 printf("Failed to setup result status shared memory\n");
   15291           0 :                 return -1;
   15292             :         }
   15293             : 
   15294          32 :         for (i = 0; i < torture_nprocs; i++) {
   15295          16 :                 child_status[i] = 0;
   15296          16 :                 child_status_out[i] = True;
   15297             :         }
   15298             : 
   15299          16 :         start = timeval_current();
   15300             : 
   15301          32 :         for (i=0;i<torture_nprocs;i++) {
   15302          16 :                 procnum = i;
   15303          16 :                 if (fork() == 0) {
   15304           0 :                         pid_t mypid = getpid();
   15305           0 :                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
   15306             : 
   15307           0 :                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
   15308             : 
   15309           0 :                         while (1) {
   15310           0 :                                 if (torture_open_connection(&current_cli, i)) break;
   15311           0 :                                 if (tries-- == 0) {
   15312           0 :                                         printf("pid %d failed to start\n", (int)getpid());
   15313           0 :                                         _exit(1);
   15314             :                                 }
   15315           0 :                                 smb_msleep(10); 
   15316             :                         }
   15317             : 
   15318           0 :                         child_status[i] = getpid();
   15319             : 
   15320           0 :                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
   15321             : 
   15322           0 :                         child_status_out[i] = fn(i);
   15323           0 :                         _exit(0);
   15324             :                 }
   15325             :         }
   15326             : 
   15327           0 :         do {
   15328          71 :                 synccount = 0;
   15329         142 :                 for (i=0;i<torture_nprocs;i++) {
   15330          71 :                         if (child_status[i]) synccount++;
   15331             :                 }
   15332          71 :                 if (synccount == torture_nprocs) break;
   15333          55 :                 smb_msleep(10);
   15334          55 :         } while (timeval_elapsed(&start) < 30);
   15335             : 
   15336          16 :         if (synccount != torture_nprocs) {
   15337           0 :                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
   15338           0 :                 *result = False;
   15339           0 :                 return timeval_elapsed(&start);
   15340             :         }
   15341             : 
   15342             :         /* start the client load */
   15343          16 :         start = timeval_current();
   15344             : 
   15345          32 :         for (i=0;i<torture_nprocs;i++) {
   15346          16 :                 child_status[i] = 0;
   15347             :         }
   15348             : 
   15349          16 :         printf("%d clients started\n", torture_nprocs);
   15350             : 
   15351          32 :         for (i=0;i<torture_nprocs;i++) {
   15352          16 :                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
   15353             :         }
   15354             : 
   15355          16 :         printf("\n");
   15356             : 
   15357          32 :         for (i=0;i<torture_nprocs;i++) {
   15358          16 :                 if (!child_status_out[i]) {
   15359           2 :                         *result = False;
   15360             :                 }
   15361             :         }
   15362          16 :         return timeval_elapsed(&start);
   15363             : }
   15364             : 
   15365             : #define FLAG_MULTIPROC 1
   15366             : 
   15367             : static struct {
   15368             :         const char *name;
   15369             :         bool (*fn)(int);
   15370             :         unsigned flags;
   15371             : } torture_ops[] = {
   15372             :         {
   15373             :                 .name = "FDPASS",
   15374             :                 .fn   = run_fdpasstest,
   15375             :         },
   15376             :         {
   15377             :                 .name = "LOCK1",
   15378             :                 .fn   = run_locktest1,
   15379             :         },
   15380             :         {
   15381             :                 .name = "LOCK2",
   15382             :                 .fn   =  run_locktest2,
   15383             :         },
   15384             :         {
   15385             :                 .name = "LOCK3",
   15386             :                 .fn   =  run_locktest3,
   15387             :         },
   15388             :         {
   15389             :                 .name = "LOCK4",
   15390             :                 .fn   =  run_locktest4,
   15391             :         },
   15392             :         {
   15393             :                 .name = "LOCK5",
   15394             :                 .fn   =  run_locktest5,
   15395             :         },
   15396             :         {
   15397             :                 .name = "LOCK6",
   15398             :                 .fn   =  run_locktest6,
   15399             :         },
   15400             :         {
   15401             :                 .name = "LOCK7",
   15402             :                 .fn   =  run_locktest7,
   15403             :         },
   15404             :         {
   15405             :                 .name = "LOCK8",
   15406             :                 .fn   =  run_locktest8,
   15407             :         },
   15408             :         {
   15409             :                 .name = "LOCK9A",
   15410             :                 .fn   =  run_locktest9a,
   15411             :         },
   15412             :         {
   15413             :                 .name = "LOCK9B",
   15414             :                 .fn   =  run_locktest9b,
   15415             :         },
   15416             :         {
   15417             :                 .name = "LOCK10",
   15418             :                 .fn   =  run_locktest10,
   15419             :         },
   15420             :         {
   15421             :                 .name = "LOCK11",
   15422             :                 .fn   =  run_locktest11,
   15423             :         },
   15424             :         {
   15425             :                 .name = "LOCK12",
   15426             :                 .fn   =  run_locktest12,
   15427             :         },
   15428             :         {
   15429             :                 .name = "LOCK13",
   15430             :                 .fn   =  run_locktest13,
   15431             :         },
   15432             :         {
   15433             :                 .name = "UNLINK",
   15434             :                 .fn   = run_unlinktest,
   15435             :         },
   15436             :         {
   15437             :                 .name = "BROWSE",
   15438             :                 .fn   = run_browsetest,
   15439             :         },
   15440             :         {
   15441             :                 .name = "ATTR",
   15442             :                 .fn   =   run_attrtest,
   15443             :         },
   15444             :         {
   15445             :                 .name = "TRANS2",
   15446             :                 .fn   = run_trans2test,
   15447             :         },
   15448             :         {
   15449             :                 .name  = "MAXFID",
   15450             :                 .fn    = run_maxfidtest,
   15451             :                 .flags = FLAG_MULTIPROC,
   15452             :         },
   15453             :         {
   15454             :                 .name  = "TORTURE",
   15455             :                 .fn    = run_torture,
   15456             :                 .flags = FLAG_MULTIPROC,
   15457             :         },
   15458             :         {
   15459             :                 .name  = "RANDOMIPC",
   15460             :                 .fn    = run_randomipc,
   15461             :         },
   15462             :         {
   15463             :                 .name  = "NEGNOWAIT",
   15464             :                 .fn    = run_negprot_nowait,
   15465             :         },
   15466             :         {
   15467             :                 .name  = "NBENCH",
   15468             :                 .fn    =  run_nbench,
   15469             :         },
   15470             :         {
   15471             :                 .name  = "NBENCH2",
   15472             :                 .fn    = run_nbench2,
   15473             :         },
   15474             :         {
   15475             :                 .name  = "OPLOCK1",
   15476             :                 .fn    =  run_oplock1,
   15477             :         },
   15478             :         {
   15479             :                 .name  = "OPLOCK2",
   15480             :                 .fn    =  run_oplock2,
   15481             :         },
   15482             :         {
   15483             :                 .name  = "OPLOCK4",
   15484             :                 .fn    =  run_oplock4,
   15485             :         },
   15486             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
   15487             :         {
   15488             :                 .name  = "OPLOCK5",
   15489             :                 .fn    =  run_oplock5,
   15490             :         },
   15491             : #endif
   15492             :         {
   15493             :                 .name  = "DIR",
   15494             :                 .fn    =  run_dirtest,
   15495             :         },
   15496             :         {
   15497             :                 .name  = "DIR1",
   15498             :                 .fn    =  run_dirtest1,
   15499             :         },
   15500             :         {
   15501             :                 .name  = "DIR-CREATETIME",
   15502             :                 .fn    =  run_dir_createtime,
   15503             :         },
   15504             :         {
   15505             :                 .name  = "DENY1",
   15506             :                 .fn    =  torture_denytest1,
   15507             :         },
   15508             :         {
   15509             :                 .name  = "DENY2",
   15510             :                 .fn    =  torture_denytest2,
   15511             :         },
   15512             :         {
   15513             :                 .name  = "TCON",
   15514             :                 .fn    =  run_tcon_test,
   15515             :         },
   15516             :         {
   15517             :                 .name  = "TCONDEV",
   15518             :                 .fn    =  run_tcon_devtype_test,
   15519             :         },
   15520             :         {
   15521             :                 .name  = "RW1",
   15522             :                 .fn    =  run_readwritetest,
   15523             :         },
   15524             :         {
   15525             :                 .name  = "RW2",
   15526             :                 .fn    =  run_readwritemulti,
   15527             :                 .flags = FLAG_MULTIPROC
   15528             :         },
   15529             :         {
   15530             :                 .name  = "RW3",
   15531             :                 .fn    =  run_readwritelarge,
   15532             :         },
   15533             :         {
   15534             :                 .name  = "RW-SIGNING",
   15535             :                 .fn    =  run_readwritelarge_signtest,
   15536             :         },
   15537             :         {
   15538             :                 .name  = "OPEN",
   15539             :                 .fn    = run_opentest,
   15540             :         },
   15541             :         {
   15542             :                 .name  = "POSIX",
   15543             :                 .fn    = run_simple_posix_open_test,
   15544             :         },
   15545             :         {
   15546             :                 .name  = "POSIX-APPEND",
   15547             :                 .fn    = run_posix_append,
   15548             :         },
   15549             :         {
   15550             :                 .name  = "POSIX-SYMLINK-ACL",
   15551             :                 .fn    = run_acl_symlink_test,
   15552             :         },
   15553             :         {
   15554             :                 .name  = "POSIX-SYMLINK-EA",
   15555             :                 .fn    = run_ea_symlink_test,
   15556             :         },
   15557             :         {
   15558             :                 .name  = "POSIX-STREAM-DELETE",
   15559             :                 .fn    = run_posix_stream_delete,
   15560             :         },
   15561             :         {
   15562             :                 .name  = "POSIX-OFD-LOCK",
   15563             :                 .fn    = run_posix_ofd_lock_test,
   15564             :         },
   15565             :         {
   15566             :                 .name  = "POSIX-BLOCKING-LOCK",
   15567             :                 .fn    = run_posix_blocking_lock,
   15568             :         },
   15569             :         {
   15570             :                 .name  = "POSIX-MKDIR",
   15571             :                 .fn    = run_posix_mkdir_test,
   15572             :         },
   15573             :         {
   15574             :                 .name  = "POSIX-ACL-OPLOCK",
   15575             :                 .fn    = run_posix_acl_oplock_test,
   15576             :         },
   15577             :         {
   15578             :                 .name  = "POSIX-ACL-SHAREROOT",
   15579             :                 .fn    = run_posix_acl_shareroot_test,
   15580             :         },
   15581             :         {
   15582             :                 .name  = "POSIX-LS-WILDCARD",
   15583             :                 .fn    = run_posix_ls_wildcard_test,
   15584             :         },
   15585             :         {
   15586             :                 .name  = "POSIX-LS-SINGLE",
   15587             :                 .fn    = run_posix_ls_single_test,
   15588             :         },
   15589             :         {
   15590             :                 .name  = "POSIX-READLINK",
   15591             :                 .fn    = run_posix_readlink_test,
   15592             :         },
   15593             :         {
   15594             :                 .name  = "POSIX-STAT",
   15595             :                 .fn    = run_posix_stat_test,
   15596             :         },
   15597             :         {
   15598             :                 .name  = "POSIX-SYMLINK-PARENT",
   15599             :                 .fn    = run_posix_symlink_parent_test,
   15600             :         },
   15601             :         {
   15602             :                 .name  = "POSIX-SYMLINK-CHMOD",
   15603             :                 .fn    = run_posix_symlink_chmod_test,
   15604             :         },
   15605             :         {
   15606             :                 .name  = "POSIX-SYMLINK-RENAME",
   15607             :                 .fn    = run_posix_symlink_rename_test,
   15608             :         },
   15609             :         {
   15610             :                 .name  = "POSIX-DIR-DEFAULT-ACL",
   15611             :                 .fn    = run_posix_dir_default_acl_test,
   15612             :         },
   15613             :         {
   15614             :                 .name  = "POSIX-SYMLINK-GETPATHINFO",
   15615             :                 .fn    = run_posix_symlink_getpathinfo_test,
   15616             :         },
   15617             :         {
   15618             :                 .name  = "POSIX-SYMLINK-SETPATHINFO",
   15619             :                 .fn    = run_posix_symlink_setpathinfo_test,
   15620             :         },
   15621             :         {
   15622             :                 .name  = "WINDOWS-BAD-SYMLINK",
   15623             :                 .fn    = run_symlink_open_test,
   15624             :         },
   15625             :         {
   15626             :                 .name  = "SMB1-WILD-MANGLE-UNLINK",
   15627             :                 .fn    = run_smb1_wild_mangle_unlink_test,
   15628             :         },
   15629             :         {
   15630             :                 .name  = "SMB1-WILD-MANGLE-RENAME",
   15631             :                 .fn    = run_smb1_wild_mangle_rename_test,
   15632             :         },
   15633             :         {
   15634             :                 .name  = "CASE-INSENSITIVE-CREATE",
   15635             :                 .fn    = run_case_insensitive_create,
   15636             :         },
   15637             :         {
   15638             :                 .name  = "ASYNC-ECHO",
   15639             :                 .fn    = run_async_echo,
   15640             :         },
   15641             :         {
   15642             :                 .name  = "UID-REGRESSION-TEST",
   15643             :                 .fn    = run_uid_regression_test,
   15644             :         },
   15645             :         {
   15646             :                 .name  = "SHORTNAME-TEST",
   15647             :                 .fn    = run_shortname_test,
   15648             :         },
   15649             :         {
   15650             :                 .name  = "ADDRCHANGE",
   15651             :                 .fn    = run_addrchange,
   15652             :         },
   15653             : #if 1
   15654             :         {
   15655             :                 .name  = "OPENATTR",
   15656             :                 .fn    = run_openattrtest,
   15657             :         },
   15658             : #endif
   15659             :         {
   15660             :                 .name  = "XCOPY",
   15661             :                 .fn    = run_xcopy,
   15662             :         },
   15663             :         {
   15664             :                 .name  = "RENAME",
   15665             :                 .fn    = run_rename,
   15666             :         },
   15667             :         {
   15668             :                 .name  = "RENAME-ACCESS",
   15669             :                 .fn    = run_rename_access,
   15670             :         },
   15671             :         {
   15672             :                 .name  = "OWNER-RIGHTS",
   15673             :                 .fn    = run_owner_rights,
   15674             :         },
   15675             :         {
   15676             :                 .name  = "DELETE",
   15677             :                 .fn    = run_deletetest,
   15678             :         },
   15679             :         {
   15680             :                 .name  = "DELETE-STREAM",
   15681             :                 .fn    = run_delete_stream,
   15682             :         },
   15683             :         {
   15684             :                 .name  = "DELETE-PRINT",
   15685             :                 .fn    = run_delete_print_test,
   15686             :         },
   15687             :         {
   15688             :                 .name  = "DELETE-LN",
   15689             :                 .fn    = run_deletetest_ln,
   15690             :         },
   15691             :         {
   15692             :                 .name  = "PROPERTIES",
   15693             :                 .fn    = run_properties,
   15694             :         },
   15695             :         {
   15696             :                 .name  = "MANGLE",
   15697             :                 .fn    = torture_mangle,
   15698             :         },
   15699             :         {
   15700             :                 .name  = "MANGLE1",
   15701             :                 .fn    = run_mangle1,
   15702             :         },
   15703             :         {
   15704             :                 .name  = "MANGLE-ILLEGAL",
   15705             :                 .fn    = run_mangle_illegal,
   15706             :         },
   15707             :         {
   15708             :                 .name  = "W2K",
   15709             :                 .fn    = run_w2ktest,
   15710             :         },
   15711             :         {
   15712             :                 .name  = "TRANS2SCAN",
   15713             :                 .fn    = torture_trans2_scan,
   15714             :         },
   15715             :         {
   15716             :                 .name  = "NTTRANSSCAN",
   15717             :                 .fn    = torture_nttrans_scan,
   15718             :         },
   15719             :         {
   15720             :                 .name  = "UTABLE",
   15721             :                 .fn    = torture_utable,
   15722             :         },
   15723             :         {
   15724             :                 .name  = "CASETABLE",
   15725             :                 .fn    = torture_casetable,
   15726             :         },
   15727             :         {
   15728             :                 .name  = "ERRMAPEXTRACT",
   15729             :                 .fn    = run_error_map_extract,
   15730             :         },
   15731             :         {
   15732             :                 .name  = "PIPE_NUMBER",
   15733             :                 .fn    = run_pipe_number,
   15734             :         },
   15735             :         {
   15736             :                 .name  = "TCON2",
   15737             :                 .fn    =  run_tcon2_test,
   15738             :         },
   15739             :         {
   15740             :                 .name  = "IOCTL",
   15741             :                 .fn    =  torture_ioctl_test,
   15742             :         },
   15743             :         {
   15744             :                 .name  = "CHKPATH",
   15745             :                 .fn    =  torture_chkpath_test,
   15746             :         },
   15747             :         {
   15748             :                 .name  = "FDSESS",
   15749             :                 .fn    = run_fdsesstest,
   15750             :         },
   15751             :         {
   15752             :                 .name  = "EATEST",
   15753             :                 .fn    = run_eatest,
   15754             :         },
   15755             :         {
   15756             :                 .name  = "SESSSETUP_BENCH",
   15757             :                 .fn    = run_sesssetup_bench,
   15758             :         },
   15759             :         {
   15760             :                 .name  = "CHAIN1",
   15761             :                 .fn    = run_chain1,
   15762             :         },
   15763             :         {
   15764             :                 .name  = "CHAIN2",
   15765             :                 .fn    = run_chain2,
   15766             :         },
   15767             :         {
   15768             :                 .name  = "CHAIN3",
   15769             :                 .fn    = run_chain3,
   15770             :         },
   15771             :         {
   15772             :                 .name  = "WINDOWS-WRITE",
   15773             :                 .fn    = run_windows_write,
   15774             :         },
   15775             :         {
   15776             :                 .name  = "LARGE_READX",
   15777             :                 .fn    = run_large_readx,
   15778             :         },
   15779             :         {
   15780             :                 .name  = "MSDFS-ATTRIBUTE",
   15781             :                 .fn    = run_msdfs_attribute,
   15782             :         },
   15783             :         {
   15784             :                 .name  = "NTTRANS-CREATE",
   15785             :                 .fn    = run_nttrans_create,
   15786             :         },
   15787             :         {
   15788             :                 .name  = "NTTRANS-FSCTL",
   15789             :                 .fn    = run_nttrans_fsctl,
   15790             :         },
   15791             :         {
   15792             :                 .name  = "CLI_ECHO",
   15793             :                 .fn    = run_cli_echo,
   15794             :         },
   15795             :         {
   15796             :                 .name  = "CLI_SPLICE",
   15797             :                 .fn    = run_cli_splice,
   15798             :         },
   15799             :         {
   15800             :                 .name  = "TLDAP",
   15801             :                 .fn    = run_tldap,
   15802             :         },
   15803             :         {
   15804             :                 .name  = "STREAMERROR",
   15805             :                 .fn    = run_streamerror,
   15806             :         },
   15807             :         {
   15808             :                 .name  = "NOTIFY-BENCH",
   15809             :                 .fn    = run_notify_bench,
   15810             :         },
   15811             :         {
   15812             :                 .name  = "NOTIFY-BENCH2",
   15813             :                 .fn    = run_notify_bench2,
   15814             :         },
   15815             :         {
   15816             :                 .name  = "NOTIFY-BENCH3",
   15817             :                 .fn    = run_notify_bench3,
   15818             :         },
   15819             :         {
   15820             :                 .name  = "BAD-NBT-SESSION",
   15821             :                 .fn    = run_bad_nbt_session,
   15822             :         },
   15823             :         {
   15824             :                 .name  = "IGN-BAD-NEGPROT",
   15825             :                 .fn    = run_ign_bad_negprot,
   15826             :         },
   15827             :         {
   15828             :                 .name  = "SMB-ANY-CONNECT",
   15829             :                 .fn    = run_smb_any_connect,
   15830             :         },
   15831             :         {
   15832             :                 .name  = "NOTIFY-ONLINE",
   15833             :                 .fn    = run_notify_online,
   15834             :         },
   15835             :         {
   15836             :                 .name  = "SMB2-BASIC",
   15837             :                 .fn    = run_smb2_basic,
   15838             :         },
   15839             :         {
   15840             :                 .name  = "SMB2-NEGPROT",
   15841             :                 .fn    = run_smb2_negprot,
   15842             :         },
   15843             :         {
   15844             :                 .name  = "SMB2-ANONYMOUS",
   15845             :                 .fn    = run_smb2_anonymous,
   15846             :         },
   15847             :         {
   15848             :                 .name  = "SMB2-SESSION-RECONNECT",
   15849             :                 .fn    = run_smb2_session_reconnect,
   15850             :         },
   15851             :         {
   15852             :                 .name  = "SMB2-TCON-DEPENDENCE",
   15853             :                 .fn    = run_smb2_tcon_dependence,
   15854             :         },
   15855             :         {
   15856             :                 .name  = "SMB2-MULTI-CHANNEL",
   15857             :                 .fn    = run_smb2_multi_channel,
   15858             :         },
   15859             :         {
   15860             :                 .name  = "SMB2-SESSION-REAUTH",
   15861             :                 .fn    = run_smb2_session_reauth,
   15862             :         },
   15863             :         {
   15864             :                 .name  = "SMB2-FTRUNCATE",
   15865             :                 .fn    = run_smb2_ftruncate,
   15866             :         },
   15867             :         {
   15868             :                 .name  = "SMB2-DIR-FSYNC",
   15869             :                 .fn    = run_smb2_dir_fsync,
   15870             :         },
   15871             :         {
   15872             :                 .name  = "SMB2-PATH-SLASH",
   15873             :                 .fn    = run_smb2_path_slash,
   15874             :         },
   15875             :         {
   15876             :                 .name  = "SMB1-SYSTEM-SECURITY",
   15877             :                 .fn    = run_smb1_system_security,
   15878             :         },
   15879             :         {
   15880             :                 .name  = "SMB2-SACL",
   15881             :                 .fn    = run_smb2_sacl,
   15882             :         },
   15883             :         {
   15884             :                 .name  = "SMB2-QUOTA1",
   15885             :                 .fn    = run_smb2_quota1,
   15886             :         },
   15887             :         {
   15888             :                 .name  = "SMB2-INVALID-PIPENAME",
   15889             :                 .fn    = run_smb2_invalid_pipename,
   15890             :         },
   15891             :         {
   15892             :                 .name  = "SMB2-STREAM-ACL",
   15893             :                 .fn    = run_smb2_stream_acl,
   15894             :         },
   15895             :         {
   15896             :                 .name  = "SMB2-LIST-DIR-ASYNC",
   15897             :                 .fn    = run_list_dir_async_test,
   15898             :         },
   15899             :         {
   15900             :                 .name  = "SMB2-DEL-ON-CLOSE-NONEMPTY",
   15901             :                 .fn    = run_delete_on_close_non_empty,
   15902             :         },
   15903             :         {
   15904             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
   15905             :                 .fn    = run_delete_on_close_nonwrite_delete_yes_test,
   15906             :         },
   15907             :         {
   15908             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
   15909             :                 .fn    = run_delete_on_close_nonwrite_delete_no_test,
   15910             :         },
   15911             :         {
   15912             :                 .name  = "SMB2-DFS-PATHS",
   15913             :                 .fn    = run_smb2_dfs_paths,
   15914             :         },
   15915             :         {
   15916             :                 .name  = "SMB2-NON-DFS-SHARE",
   15917             :                 .fn    = run_smb2_non_dfs_share,
   15918             :         },
   15919             :         {
   15920             :                 .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
   15921             :                 .fn    = run_smb2_dfs_share_non_dfs_path,
   15922             :         },
   15923             :         {
   15924             :                 .name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
   15925             :                 .fn    = run_smb2_dfs_filename_leading_backslash,
   15926             :         },
   15927             :         {
   15928             :                 .name  = "SMB2-PIPE-READ-ASYNC-DISCONNECT",
   15929             :                 .fn    = run_smb2_pipe_read_async_disconnect,
   15930             :         },
   15931             :         {
   15932             :                 .name  = "SMB1-TRUNCATED-SESSSETUP",
   15933             :                 .fn    = run_smb1_truncated_sesssetup,
   15934             :         },
   15935             :         {
   15936             :                 .name  = "SMB1-NEGOTIATE-EXIT",
   15937             :                 .fn    = run_smb1_negotiate_exit,
   15938             :         },
   15939             :         {
   15940             :                 .name  = "SMB1-NEGOTIATE-TCON",
   15941             :                 .fn    = run_smb1_negotiate_tcon,
   15942             :         },
   15943             :         {
   15944             :                 .name  = "SMB1-DFS-PATHS",
   15945             :                 .fn    = run_smb1_dfs_paths,
   15946             :         },
   15947             :         {
   15948             :                 .name  = "SMB1-DFS-SEARCH-PATHS",
   15949             :                 .fn    = run_smb1_dfs_search_paths,
   15950             :         },
   15951             :         {
   15952             :                 .name  = "SMB1-DFS-OPERATIONS",
   15953             :                 .fn    = run_smb1_dfs_operations,
   15954             :         },
   15955             :         {
   15956             :                 .name  = "SMB1-DFS-BADPATH",
   15957             :                 .fn    = run_smb1_dfs_check_badpath,
   15958             :         },
   15959             :         {
   15960             :                 .name  = "CLEANUP1",
   15961             :                 .fn    = run_cleanup1,
   15962             :         },
   15963             :         {
   15964             :                 .name  = "CLEANUP2",
   15965             :                 .fn    = run_cleanup2,
   15966             :         },
   15967             :         {
   15968             :                 .name  = "CLEANUP4",
   15969             :                 .fn    = run_cleanup4,
   15970             :         },
   15971             :         {
   15972             :                 .name  = "OPLOCK-CANCEL",
   15973             :                 .fn    = run_oplock_cancel,
   15974             :         },
   15975             :         {
   15976             :                 .name  = "PIDHIGH",
   15977             :                 .fn    = run_pidhigh,
   15978             :         },
   15979             :         {
   15980             :                 .name  = "LOCAL-SUBSTITUTE",
   15981             :                 .fn    = run_local_substitute,
   15982             :         },
   15983             :         {
   15984             :                 .name  = "LOCAL-GENCACHE",
   15985             :                 .fn    = run_local_gencache,
   15986             :         },
   15987             :         {
   15988             :                 .name  = "LOCAL-DBWRAP-WATCH1",
   15989             :                 .fn    = run_dbwrap_watch1,
   15990             :         },
   15991             :         {
   15992             :                 .name  = "LOCAL-DBWRAP-WATCH2",
   15993             :                 .fn    = run_dbwrap_watch2,
   15994             :         },
   15995             :         {
   15996             :                 .name  = "LOCAL-DBWRAP-WATCH3",
   15997             :                 .fn    = run_dbwrap_watch3,
   15998             :         },
   15999             :         {
   16000             :                 .name  = "LOCAL-DBWRAP-WATCH4",
   16001             :                 .fn    = run_dbwrap_watch4,
   16002             :         },
   16003             :         {
   16004             :                 .name  = "LOCAL-DBWRAP-DO-LOCKED1",
   16005             :                 .fn    = run_dbwrap_do_locked1,
   16006             :         },
   16007             :         {
   16008             :                 .name  = "LOCAL-MESSAGING-READ1",
   16009             :                 .fn    = run_messaging_read1,
   16010             :         },
   16011             :         {
   16012             :                 .name  = "LOCAL-MESSAGING-READ2",
   16013             :                 .fn    = run_messaging_read2,
   16014             :         },
   16015             :         {
   16016             :                 .name  = "LOCAL-MESSAGING-READ3",
   16017             :                 .fn    = run_messaging_read3,
   16018             :         },
   16019             :         {
   16020             :                 .name  = "LOCAL-MESSAGING-READ4",
   16021             :                 .fn    = run_messaging_read4,
   16022             :         },
   16023             :         {
   16024             :                 .name  = "LOCAL-MESSAGING-FDPASS1",
   16025             :                 .fn    = run_messaging_fdpass1,
   16026             :         },
   16027             :         {
   16028             :                 .name  = "LOCAL-MESSAGING-FDPASS2",
   16029             :                 .fn    = run_messaging_fdpass2,
   16030             :         },
   16031             :         {
   16032             :                 .name  = "LOCAL-MESSAGING-FDPASS2a",
   16033             :                 .fn    = run_messaging_fdpass2a,
   16034             :         },
   16035             :         {
   16036             :                 .name  = "LOCAL-MESSAGING-FDPASS2b",
   16037             :                 .fn    = run_messaging_fdpass2b,
   16038             :         },
   16039             :         {
   16040             :                 .name  = "LOCAL-MESSAGING-SEND-ALL",
   16041             :                 .fn    = run_messaging_send_all,
   16042             :         },
   16043             :         {
   16044             :                 .name  = "LOCAL-BASE64",
   16045             :                 .fn    = run_local_base64,
   16046             :         },
   16047             :         {
   16048             :                 .name  = "LOCAL-RBTREE",
   16049             :                 .fn    = run_local_rbtree,
   16050             :         },
   16051             :         {
   16052             :                 .name  = "LOCAL-MEMCACHE",
   16053             :                 .fn    = run_local_memcache,
   16054             :         },
   16055             :         {
   16056             :                 .name  = "LOCAL-STREAM-NAME",
   16057             :                 .fn    = run_local_stream_name,
   16058             :         },
   16059             :         {
   16060             :                 .name  = "LOCAL-STR-MATCH-MSWILD",
   16061             :                 .fn    = run_str_match_mswild,
   16062             :         },
   16063             :         {
   16064             :                 .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
   16065             :                 .fn    = run_str_match_regex_sub1,
   16066             :         },
   16067             :         {
   16068             :                 .name  = "WBCLIENT-MULTI-PING",
   16069             :                 .fn    = run_wbclient_multi_ping,
   16070             :         },
   16071             :         {
   16072             :                 .name  = "LOCAL-string_to_sid",
   16073             :                 .fn    = run_local_string_to_sid,
   16074             :         },
   16075             :         {
   16076             :                 .name  = "LOCAL-sid_to_string",
   16077             :                 .fn    = run_local_sid_to_string,
   16078             :         },
   16079             :         {
   16080             :                 .name  = "LOCAL-binary_to_sid",
   16081             :                 .fn    = run_local_binary_to_sid,
   16082             :         },
   16083             :         {
   16084             :                 .name  = "LOCAL-DBTRANS",
   16085             :                 .fn    = run_local_dbtrans,
   16086             :         },
   16087             :         {
   16088             :                 .name  = "LOCAL-TEVENT-POLL",
   16089             :                 .fn    = run_local_tevent_poll,
   16090             :         },
   16091             :         {
   16092             :                 .name  = "LOCAL-CONVERT-STRING",
   16093             :                 .fn    = run_local_convert_string,
   16094             :         },
   16095             :         {
   16096             :                 .name  = "LOCAL-CONV-AUTH-INFO",
   16097             :                 .fn    = run_local_conv_auth_info,
   16098             :         },
   16099             :         {
   16100             :                 .name  = "LOCAL-hex_encode_buf",
   16101             :                 .fn    = run_local_hex_encode_buf,
   16102             :         },
   16103             :         {
   16104             :                 .name  = "LOCAL-IDMAP-TDB-COMMON",
   16105             :                 .fn    = run_idmap_tdb_common_test,
   16106             :         },
   16107             :         {
   16108             :                 .name  = "LOCAL-remove_duplicate_addrs2",
   16109             :                 .fn    = run_local_remove_duplicate_addrs2,
   16110             :         },
   16111             :         {
   16112             :                 .name  = "local-tdb-opener",
   16113             :                 .fn    = run_local_tdb_opener,
   16114             :         },
   16115             :         {
   16116             :                 .name  = "local-tdb-writer",
   16117             :                 .fn    = run_local_tdb_writer,
   16118             :         },
   16119             :         {
   16120             :                 .name  = "LOCAL-DBWRAP-CTDB1",
   16121             :                 .fn    = run_local_dbwrap_ctdb1,
   16122             :         },
   16123             :         {
   16124             :                 .name  = "LOCAL-BENCH-PTHREADPOOL",
   16125             :                 .fn    = run_bench_pthreadpool,
   16126             :         },
   16127             :         {
   16128             :                 .name  = "LOCAL-PTHREADPOOL-TEVENT",
   16129             :                 .fn    = run_pthreadpool_tevent,
   16130             :         },
   16131             :         {
   16132             :                 .name  = "LOCAL-G-LOCK1",
   16133             :                 .fn    = run_g_lock1,
   16134             :         },
   16135             :         {
   16136             :                 .name  = "LOCAL-G-LOCK2",
   16137             :                 .fn    = run_g_lock2,
   16138             :         },
   16139             :         {
   16140             :                 .name  = "LOCAL-G-LOCK3",
   16141             :                 .fn    = run_g_lock3,
   16142             :         },
   16143             :         {
   16144             :                 .name  = "LOCAL-G-LOCK4",
   16145             :                 .fn    = run_g_lock4,
   16146             :         },
   16147             :         {
   16148             :                 .name  = "LOCAL-G-LOCK4A",
   16149             :                 .fn    = run_g_lock4a,
   16150             :         },
   16151             :         {
   16152             :                 .name  = "LOCAL-G-LOCK5",
   16153             :                 .fn    = run_g_lock5,
   16154             :         },
   16155             :         {
   16156             :                 .name  = "LOCAL-G-LOCK6",
   16157             :                 .fn    = run_g_lock6,
   16158             :         },
   16159             :         {
   16160             :                 .name  = "LOCAL-G-LOCK7",
   16161             :                 .fn    = run_g_lock7,
   16162             :         },
   16163             :         {
   16164             :                 .name  = "LOCAL-G-LOCK8",
   16165             :                 .fn    = run_g_lock8,
   16166             :         },
   16167             :         {
   16168             :                 .name  = "LOCAL-G-LOCK-PING-PONG",
   16169             :                 .fn    = run_g_lock_ping_pong,
   16170             :         },
   16171             :         {
   16172             :                 .name  = "LOCAL-CANONICALIZE-PATH",
   16173             :                 .fn    = run_local_canonicalize_path,
   16174             :         },
   16175             :         {
   16176             :                 .name  = "LOCAL-NAMEMAP-CACHE1",
   16177             :                 .fn    = run_local_namemap_cache1,
   16178             :         },
   16179             :         {
   16180             :                 .name  = "LOCAL-IDMAP-CACHE1",
   16181             :                 .fn    = run_local_idmap_cache1,
   16182             :         },
   16183             :         {
   16184             :                 .name  = "qpathinfo-bufsize",
   16185             :                 .fn    = run_qpathinfo_bufsize,
   16186             :         },
   16187             :         {
   16188             :                 .name  = "hide-new-files-timeout",
   16189             :                 .fn    = run_hidenewfiles,
   16190             :         },
   16191             :         {
   16192             :                 .name  = "hide-new-files-timeout-showdirs",
   16193             :                 .fn    = run_hidenewfiles_showdirs,
   16194             :         },
   16195             : #ifdef CLUSTER_SUPPORT
   16196             :         {
   16197             :                 .name  = "ctdbd-conn1",
   16198             :                 .fn    = run_ctdbd_conn1,
   16199             :         },
   16200             : #endif
   16201             :         {
   16202             :                 .name  = "readdir-timestamp",
   16203             :                 .fn    = run_readdir_timestamp,
   16204             :         },
   16205             :         {
   16206             :                 .name  = "rpc-scale",
   16207             :                 .fn    = run_rpc_scale,
   16208             :         },
   16209             :         {
   16210             :                 .name  = "LOCAL-TDB-VALIDATE",
   16211             :                 .fn    = run_tdb_validate,
   16212             :         },
   16213             :         {
   16214             :                 .name = NULL,
   16215             :         },
   16216             : };
   16217             : 
   16218             : /****************************************************************************
   16219             : run a specified test or "ALL"
   16220             : ****************************************************************************/
   16221         546 : static bool run_test(const char *name)
   16222             : {
   16223         546 :         bool ret = True;
   16224         546 :         bool result = True;
   16225         546 :         bool found = False;
   16226          45 :         int i;
   16227          45 :         double t;
   16228         546 :         if (strequal(name,"ALL")) {
   16229           0 :                 for (i=0;torture_ops[i].name;i++) {
   16230           0 :                         run_test(torture_ops[i].name);
   16231             :                 }
   16232           0 :                 found = True;
   16233             :         }
   16234             : 
   16235      113747 :         for (i=0;torture_ops[i].name;i++) {
   16236      113197 :                 fstr_sprintf(randomfname, "\\XX%x", 
   16237      113197 :                          (unsigned)random());
   16238             : 
   16239      113197 :                 if (strequal(name, torture_ops[i].name)) {
   16240         546 :                         found = True;
   16241         546 :                         printf("Running %s\n", name);
   16242         546 :                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
   16243          16 :                                 t = create_procs(torture_ops[i].fn, &result);
   16244          16 :                                 if (!result) { 
   16245           2 :                                         ret = False;
   16246           2 :                                         printf("TEST %s FAILED!\n", name);
   16247             :                                 }
   16248             :                         } else {
   16249          45 :                                 struct timeval start;
   16250         530 :                                 start = timeval_current();
   16251         530 :                                 if (!torture_ops[i].fn(0)) {
   16252          14 :                                         ret = False;
   16253          14 :                                         printf("TEST %s FAILED!\n", name);
   16254             :                                 }
   16255         534 :                                 t = timeval_elapsed(&start);
   16256             :                         }
   16257        9995 :                         printf("%s took %g secs\n\n", name, t);
   16258             :                 }
   16259             :         }
   16260             : 
   16261         550 :         if (!found) {
   16262           0 :                 printf("Did not find a test named %s\n", name);
   16263           0 :                 ret = False;
   16264             :         }
   16265             : 
   16266         550 :         return ret;
   16267             : }
   16268             : 
   16269             : 
   16270           0 : static void usage(void)
   16271             : {
   16272           0 :         int i;
   16273             : 
   16274           0 :         printf("WARNING samba4 test suite is much more complete nowadays.\n");
   16275           0 :         printf("Please use samba4 torture.\n\n");
   16276             : 
   16277           0 :         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
   16278             : 
   16279           0 :         printf("\t-d debuglevel\n");
   16280           0 :         printf("\t-U user%%pass\n");
   16281           0 :         printf("\t-k                    use kerberos\n");
   16282           0 :         printf("\t-N numprocs\n");
   16283           0 :         printf("\t-n my_netbios_name\n");
   16284           0 :         printf("\t-W workgroup\n");
   16285           0 :         printf("\t-o num_operations\n");
   16286           0 :         printf("\t-O socket_options\n");
   16287           0 :         printf("\t-m maximum protocol\n");
   16288           0 :         printf("\t-L use oplocks\n");
   16289           0 :         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
   16290           0 :         printf("\t-A showall\n");
   16291           0 :         printf("\t-p port\n");
   16292           0 :         printf("\t-s seed\n");
   16293           0 :         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
   16294           0 :         printf("\t-f filename           filename to test\n");
   16295           0 :         printf("\t-e                    encrypt\n");
   16296           0 :         printf("\n\n");
   16297             : 
   16298           0 :         printf("tests are:");
   16299           0 :         for (i=0;torture_ops[i].name;i++) {
   16300           0 :                 printf(" %s", torture_ops[i].name);
   16301             :         }
   16302           0 :         printf("\n");
   16303             : 
   16304           0 :         printf("default test is ALL\n");
   16305             : 
   16306           0 :         exit(1);
   16307             : }
   16308             : 
   16309             : /****************************************************************************
   16310             :   main program
   16311             : ****************************************************************************/
   16312         546 :  int main(int argc,char *argv[])
   16313             : {
   16314          45 :         int opt, i;
   16315          45 :         char *p;
   16316         546 :         int gotuser = 0;
   16317         546 :         int gotpass = 0;
   16318         546 :         bool correct = True;
   16319         546 :         TALLOC_CTX *frame = talloc_stackframe();
   16320         546 :         int seed = time(NULL);
   16321         546 :         struct loadparm_context *lp_ctx = NULL;
   16322             : 
   16323             : #ifdef HAVE_SETBUFFER
   16324         546 :         setbuffer(stdout, NULL, 0);
   16325             : #endif
   16326             : 
   16327         546 :         setup_logging("smbtorture", DEBUG_STDOUT);
   16328             : 
   16329         546 :         smb_init_locale();
   16330         546 :         fault_setup();
   16331             : 
   16332         546 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
   16333         546 :         if (lp_ctx == NULL) {
   16334           0 :                 fprintf(stderr,
   16335             :                         "Failed to initialise the global parameter structure.\n");
   16336           0 :                 return 1;
   16337             :         }
   16338             : 
   16339         546 :         if (is_default_dyn_CONFIGFILE()) {
   16340         546 :                 if(getenv("SMB_CONF_PATH")) {
   16341         546 :                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
   16342             :                 }
   16343             :         }
   16344         546 :         lp_load_global(get_dyn_CONFIGFILE());
   16345         546 :         load_interfaces();
   16346             : 
   16347         546 :         if (argc < 2) {
   16348           0 :                 usage();
   16349             :         }
   16350             : 
   16351       11065 :         for(p = argv[1]; *p; p++)
   16352       10519 :           if(*p == '\\')
   16353           0 :             *p = '/';
   16354             : 
   16355         546 :         if (strncmp(argv[1], "//", 2)) {
   16356           0 :                 usage();
   16357             :         }
   16358             : 
   16359         546 :         fstrcpy(host, &argv[1][2]);
   16360         546 :         p = strchr_m(&host[2],'/');
   16361         546 :         if (!p) {
   16362           0 :                 usage();
   16363             :         }
   16364         546 :         *p = 0;
   16365         546 :         fstrcpy(share, p+1);
   16366             : 
   16367         546 :         fstrcpy(myname, get_myname(talloc_tos()));
   16368         546 :         if (!*myname) {
   16369           0 :                 fprintf(stderr, "Failed to get my hostname.\n");
   16370           0 :                 return 1;
   16371             :         }
   16372             : 
   16373         546 :         if (*username == 0 && getenv("LOGNAME")) {
   16374           0 :           fstrcpy(username,getenv("LOGNAME"));
   16375             :         }
   16376             : 
   16377         546 :         argc--;
   16378         546 :         argv++;
   16379             : 
   16380         546 :         fstrcpy(workgroup, lp_workgroup());
   16381             : 
   16382        1729 :         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
   16383        1774 :                != EOF) {
   16384        1228 :                 switch (opt) {
   16385           0 :                 case 'p':
   16386           0 :                         port_to_use = atoi(optarg);
   16387           0 :                         break;
   16388           0 :                 case 's':
   16389           0 :                         seed = atoi(optarg);
   16390           0 :                         break;
   16391           0 :                 case 'W':
   16392           0 :                         fstrcpy(workgroup,optarg);
   16393           0 :                         break;
   16394          33 :                 case 'm':
   16395          33 :                         lpcfg_set_cmdline(lp_ctx, "client max protocol", optarg);
   16396          33 :                         break;
   16397           0 :                 case 'N':
   16398           0 :                         torture_nprocs = atoi(optarg);
   16399           0 :                         break;
   16400           0 :                 case 'o':
   16401           0 :                         torture_numops = atoi(optarg);
   16402           0 :                         break;
   16403           0 :                 case 'd':
   16404           0 :                         lpcfg_set_cmdline(lp_ctx, "log level", optarg);
   16405           0 :                         break;
   16406           0 :                 case 'O':
   16407           0 :                         sockops = optarg;
   16408           0 :                         break;
   16409           0 :                 case 'L':
   16410           0 :                         use_oplocks = True;
   16411           0 :                         break;
   16412         463 :                 case 'l':
   16413         463 :                         local_path = optarg;
   16414         463 :                         break;
   16415           0 :                 case 'A':
   16416           0 :                         torture_showall = True;
   16417           0 :                         break;
   16418           0 :                 case 'n':
   16419           0 :                         fstrcpy(myname, optarg);
   16420           0 :                         break;
   16421           0 :                 case 'c':
   16422           0 :                         client_txt = optarg;
   16423           0 :                         break;
   16424         182 :                 case 'e':
   16425         182 :                         do_encrypt = true;
   16426         182 :                         break;
   16427           0 :                 case 'k':
   16428             : #ifdef HAVE_KRB5
   16429           0 :                         use_kerberos = True;
   16430             : #else
   16431             :                         d_printf("No kerberos support compiled in\n");
   16432             :                         exit(1);
   16433             : #endif
   16434           0 :                         break;
   16435         546 :                 case 'U':
   16436         546 :                         gotuser = 1;
   16437         546 :                         fstrcpy(username,optarg);
   16438         546 :                         p = strchr_m(username,'%');
   16439         546 :                         if (p) {
   16440         546 :                                 *p = 0;
   16441         546 :                                 fstrcpy(password, p+1);
   16442         546 :                                 gotpass = 1;
   16443             :                         }
   16444         501 :                         break;
   16445           0 :                 case 'b':
   16446           0 :                         fstrcpy(multishare_conn_fname, optarg);
   16447           0 :                         use_multishare_conn = True;
   16448           0 :                         break;
   16449           0 :                 case 'B':
   16450           0 :                         torture_blocksize = atoi(optarg);
   16451           0 :                         break;
   16452           4 :                 case 'f':
   16453           4 :                         test_filename = SMB_STRDUP(optarg);
   16454           4 :                         break;
   16455           0 :                 default:
   16456           0 :                         printf("Unknown option %c (%d)\n", (char)opt, opt);
   16457           0 :                         usage();
   16458             :                 }
   16459             :         }
   16460             : 
   16461         546 :         d_printf("using seed %d\n", seed);
   16462             : 
   16463         546 :         srandom(seed);
   16464             : 
   16465         546 :         if(use_kerberos && !gotuser) gotpass = True;
   16466             : 
   16467         546 :         while (!gotpass) {
   16468           0 :                 char pwd[256] = {0};
   16469           0 :                 int rc;
   16470             : 
   16471           0 :                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
   16472           0 :                 if (rc == 0) {
   16473           0 :                         fstrcpy(password, pwd);
   16474           0 :                         gotpass = 1;
   16475             :                 }
   16476             :         }
   16477             : 
   16478         546 :         printf("host=%s share=%s user=%s myname=%s\n", 
   16479             :                host, share, username, myname);
   16480             : 
   16481         546 :         torture_creds = cli_session_creds_init(frame,
   16482             :                                                username,
   16483             :                                                workgroup,
   16484             :                                                NULL, /* realm */
   16485             :                                                password,
   16486             :                                                use_kerberos,
   16487             :                                                false, /* fallback_after_kerberos */
   16488             :                                                false, /* use_ccache */
   16489             :                                                false); /* password_is_nt_hash */
   16490         546 :         if (torture_creds == NULL) {
   16491           0 :                 d_printf("cli_session_creds_init() failed.\n");
   16492           0 :                 exit(1);
   16493             :         }
   16494             : 
   16495         546 :         if (argc == optind) {
   16496           0 :                 correct = run_test("ALL");
   16497             :         } else {
   16498        1096 :                 for (i=optind;i<argc;i++) {
   16499         546 :                         if (!run_test(argv[i])) {
   16500          16 :                                 correct = False;
   16501             :                         }
   16502             :                 }
   16503             :         }
   16504             : 
   16505         550 :         TALLOC_FREE(frame);
   16506             : 
   16507         550 :         if (correct) {
   16508         485 :                 return(0);
   16509             :         } else {
   16510          16 :                 return(1);
   16511             :         }
   16512             : }

Generated by: LCOV version 1.14